summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-05-08 18:27:29 -0400
committerGravatar ReinUsesLisp2019-06-20 21:36:12 -0300
commitb347543e8341ae323ea232d47df2c144fe21c739 (patch)
treeca0e48c61dea6e78b073a885ec4e5f96755f7cc1 /src
parenttexture_cache: Correct premature texceptions (diff)
downloadyuzu-b347543e8341ae323ea232d47df2c144fe21c739.tar.gz
yuzu-b347543e8341ae323ea232d47df2c144fe21c739.tar.xz
yuzu-b347543e8341ae323ea232d47df2c144fe21c739.zip
Reduce amount of size calculations.
Diffstat (limited to 'src')
-rw-r--r--src/common/common_funcs.h11
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h2
-rw-r--r--src/video_core/texture_cache/surface_base.cpp22
-rw-r--r--src/video_core/texture_cache/surface_base.h28
-rw-r--r--src/video_core/texture_cache/surface_params.cpp31
-rw-r--r--src/video_core/texture_cache/surface_params.h50
-rw-r--r--src/video_core/texture_cache/texture_cache.h40
8 files changed, 97 insertions, 88 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 8b0d34da6..00a5698f3 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <algorithm>
7#include <string> 8#include <string>
8 9
9#if !defined(ARCHITECTURE_x86_64) 10#if !defined(ARCHITECTURE_x86_64)
@@ -60,4 +61,14 @@ constexpr u32 MakeMagic(char a, char b, char c, char d) {
60 return a | b << 8 | c << 16 | d << 24; 61 return a | b << 8 | c << 16 | d << 24;
61} 62}
62 63
64template <class ForwardIt, class T, class Compare = std::less<>>
65ForwardIt BinaryFind(ForwardIt first, ForwardIt last, const T& value, Compare comp = {}) {
66 // Note: BOTH type T and the type after ForwardIt is dereferenced
67 // must be implicitly convertible to BOTH Type1 and Type2, used in Compare.
68 // This is stricter than lower_bound requirement (see above)
69
70 first = std::lower_bound(first, last, value, comp);
71 return first != last && !comp(value, *first) ? first : last;
72}
73
63} // namespace Common 74} // namespace Common
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index a58e3a816..32cb08963 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -240,7 +240,6 @@ CachedSurface::~CachedSurface() {
240} 240}
241 241
242void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) { 242void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
243 LOG_CRITICAL(Render_OpenGL, "Flushing");
244 MICROPROFILE_SCOPE(OpenGL_Texture_Download); 243 MICROPROFILE_SCOPE(OpenGL_Texture_Download);
245 244
246 // TODO(Rodrigo): Optimize alignment 245 // TODO(Rodrigo): Optimize alignment
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 1ad01137b..0a1b57014 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -133,7 +133,7 @@ protected:
133 const VideoCommon::CopyParams& copy_params) override; 133 const VideoCommon::CopyParams& copy_params) override;
134 134
135 void ImageBlit(Surface src_surface, Surface dst_surface, const Common::Rectangle<u32>& src_rect, 135 void ImageBlit(Surface src_surface, Surface dst_surface, const Common::Rectangle<u32>& src_rect,
136 const Common::Rectangle<u32>& dst_rect) override; 136 const Common::Rectangle<u32>& dst_rect) override;
137 137
138private: 138private:
139 OGLFramebuffer src_framebuffer; 139 OGLFramebuffer src_framebuffer;
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp
index dc5013240..36ca72b4a 100644
--- a/src/video_core/texture_cache/surface_base.cpp
+++ b/src/video_core/texture_cache/surface_base.cpp
@@ -19,19 +19,27 @@ using Tegra::Texture::ConvertFromGuestToHost;
19using VideoCore::MortonSwizzleMode; 19using VideoCore::MortonSwizzleMode;
20 20
21SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) 21SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params)
22 : params{params}, gpu_addr{gpu_addr}, layer_size{params.GetGuestLayerSize()}, 22 : params{params}, mipmap_sizes(params.num_levels),
23 guest_memory_size{params.GetGuestSizeInBytes()}, host_memory_size{ 23 mipmap_offsets(params.num_levels), gpu_addr{gpu_addr}, host_memory_size{
24 params.GetHostSizeInBytes()} { 24 params.GetHostSizeInBytes()} {
25 mipmap_offsets.reserve(params.num_levels);
26 mipmap_sizes.reserve(params.num_levels);
27 25
28 std::size_t offset = 0; 26 std::size_t offset = 0;
29 for (u32 level = 0; level < params.num_levels; ++level) { 27 for (u32 level = 0; level < params.num_levels; ++level) {
30 const std::size_t mipmap_size{params.GetGuestMipmapSize(level)}; 28 const std::size_t mipmap_size{params.GetGuestMipmapSize(level)};
31 mipmap_sizes.push_back(mipmap_size); 29 mipmap_sizes[level] = mipmap_size;
32 mipmap_offsets.push_back(offset); 30 mipmap_offsets[level] = offset;
33 offset += mipmap_size; 31 offset += mipmap_size;
34 } 32 }
33 layer_size = offset;
34 if (params.is_layered) {
35 if (params.is_tiled) {
36 layer_size =
37 SurfaceParams::AlignLayered(layer_size, params.block_height, params.block_depth);
38 }
39 guest_memory_size = layer_size * params.depth;
40 } else {
41 guest_memory_size = layer_size;
42 }
35} 43}
36 44
37void SurfaceBaseImpl::SwizzleFunc(MortonSwizzleMode mode, u8* memory, const SurfaceParams& params, 45void SurfaceBaseImpl::SwizzleFunc(MortonSwizzleMode mode, u8* memory, const SurfaceParams& params,
diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h
index 179e80ddb..095deb602 100644
--- a/src/video_core/texture_cache/surface_base.h
+++ b/src/video_core/texture_cache/surface_base.h
@@ -9,6 +9,7 @@
9#include <vector> 9#include <vector>
10 10
11#include "common/assert.h" 11#include "common/assert.h"
12#include "common/common_funcs.h"
12#include "common/common_types.h" 13#include "common/common_types.h"
13#include "video_core/gpu.h" 14#include "video_core/gpu.h"
14#include "video_core/morton.h" 15#include "video_core/morton.h"
@@ -16,16 +17,6 @@
16#include "video_core/texture_cache/surface_params.h" 17#include "video_core/texture_cache/surface_params.h"
17#include "video_core/texture_cache/surface_view.h" 18#include "video_core/texture_cache/surface_view.h"
18 19
19template <class ForwardIt, class T, class Compare = std::less<>>
20ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, Compare comp = {}) {
21 // Note: BOTH type T and the type after ForwardIt is dereferenced
22 // must be implicitly convertible to BOTH Type1 and Type2, used in Compare.
23 // This is stricter than lower_bound requirement (see above)
24
25 first = std::lower_bound(first, last, value, comp);
26 return first != last && !comp(value, *first) ? first : last;
27}
28
29namespace Tegra { 20namespace Tegra {
30class MemoryManager; 21class MemoryManager;
31} 22}
@@ -153,7 +144,7 @@ public:
153 const auto layer{static_cast<u32>(relative_address / layer_size)}; 144 const auto layer{static_cast<u32>(relative_address / layer_size)};
154 const GPUVAddr mipmap_address = relative_address - layer_size * layer; 145 const GPUVAddr mipmap_address = relative_address - layer_size * layer;
155 const auto mipmap_it = 146 const auto mipmap_it =
156 binary_find(mipmap_offsets.begin(), mipmap_offsets.end(), mipmap_address); 147 Common::BinaryFind(mipmap_offsets.begin(), mipmap_offsets.end(), mipmap_address);
157 if (mipmap_it == mipmap_offsets.end()) { 148 if (mipmap_it == mipmap_offsets.end()) {
158 return {}; 149 return {};
159 } 150 }
@@ -172,8 +163,8 @@ protected:
172 virtual void DecorateSurfaceName() = 0; 163 virtual void DecorateSurfaceName() = 0;
173 164
174 const SurfaceParams params; 165 const SurfaceParams params;
175 const std::size_t layer_size; 166 std::size_t layer_size;
176 const std::size_t guest_memory_size; 167 std::size_t guest_memory_size;
177 const std::size_t host_memory_size; 168 const std::size_t host_memory_size;
178 GPUVAddr gpu_addr{}; 169 GPUVAddr gpu_addr{};
179 CacheAddr cache_addr{}; 170 CacheAddr cache_addr{};
@@ -268,9 +259,11 @@ public:
268 return GetView(ViewParams(overview_params.target, 0, num_layers, 0, params.num_levels)); 259 return GetView(ViewParams(overview_params.target, 0, num_layers, 0, params.num_levels));
269 } 260 }
270 261
271 std::optional<TView> EmplaceView(const SurfaceParams& view_params, const GPUVAddr view_addr) { 262 std::optional<TView> EmplaceView(const SurfaceParams& view_params, const GPUVAddr view_addr,
272 if (view_addr < gpu_addr || params.target == SurfaceTarget::Texture3D || 263 const std::size_t candidate_size) {
273 params.num_levels == 1 || view_params.target == SurfaceTarget::Texture3D) { 264 if (params.target == SurfaceTarget::Texture3D ||
265 (params.num_levels == 1 && !params.is_layered) ||
266 view_params.target == SurfaceTarget::Texture3D) {
274 return {}; 267 return {};
275 } 268 }
276 const auto layer_mipmap{GetLayerMipmap(view_addr)}; 269 const auto layer_mipmap{GetLayerMipmap(view_addr)};
@@ -279,8 +272,7 @@ public:
279 } 272 }
280 const u32 layer{layer_mipmap->first}; 273 const u32 layer{layer_mipmap->first};
281 const u32 mipmap{layer_mipmap->second}; 274 const u32 mipmap{layer_mipmap->second};
282 const std::size_t size{view_params.GetGuestSizeInBytes()}; 275 if (GetMipmapSize(mipmap) != candidate_size) {
283 if (GetMipmapSize(mipmap) != size) {
284 // TODO: The view may cover many mimaps, this case can still go on. 276 // TODO: The view may cover many mimaps, this case can still go on.
285 // This edge-case can be safely be ignored since it will just result in worse 277 // This edge-case can be safely be ignored since it will just result in worse
286 // performance. 278 // performance.
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp
index d9052152c..b537b26e2 100644
--- a/src/video_core/texture_cache/surface_params.cpp
+++ b/src/video_core/texture_cache/surface_params.cpp
@@ -4,13 +4,12 @@
4 4
5#include <map> 5#include <map>
6 6
7#include "common/cityhash.h"
8#include "common/alignment.h" 7#include "common/alignment.h"
8#include "common/cityhash.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "video_core/engines/shader_bytecode.h" 10#include "video_core/engines/shader_bytecode.h"
11#include "video_core/surface.h" 11#include "video_core/surface.h"
12#include "video_core/texture_cache/surface_params.h" 12#include "video_core/texture_cache/surface_params.h"
13#include "video_core/textures/decoders.h"
14 13
15namespace VideoCommon { 14namespace VideoCommon {
16 15
@@ -169,18 +168,6 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface(
169 return params; 168 return params;
170} 169}
171 170
172u32 SurfaceParams::GetMipWidth(u32 level) const {
173 return std::max(1U, width >> level);
174}
175
176u32 SurfaceParams::GetMipHeight(u32 level) const {
177 return std::max(1U, height >> level);
178}
179
180u32 SurfaceParams::GetMipDepth(u32 level) const {
181 return is_layered ? depth : std::max(1U, depth >> level);
182}
183
184bool SurfaceParams::IsLayered() const { 171bool SurfaceParams::IsLayered() const {
185 switch (target) { 172 switch (target) {
186 case SurfaceTarget::Texture1DArray: 173 case SurfaceTarget::Texture1DArray:
@@ -275,22 +262,6 @@ std::size_t SurfaceParams::GetHostLayerSize(u32 level) const {
275 return GetInnerMipmapMemorySize(level, true, false); 262 return GetInnerMipmapMemorySize(level, true, false);
276} 263}
277 264
278u32 SurfaceParams::GetDefaultBlockWidth() const {
279 return VideoCore::Surface::GetDefaultBlockWidth(pixel_format);
280}
281
282u32 SurfaceParams::GetDefaultBlockHeight() const {
283 return VideoCore::Surface::GetDefaultBlockHeight(pixel_format);
284}
285
286u32 SurfaceParams::GetBitsPerPixel() const {
287 return VideoCore::Surface::GetFormatBpp(pixel_format);
288}
289
290u32 SurfaceParams::GetBytesPerPixel() const {
291 return VideoCore::Surface::GetBytesPerPixel(pixel_format);
292}
293
294bool SurfaceParams::IsPixelFormatZeta() const { 265bool SurfaceParams::IsPixelFormatZeta() const {
295 return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat && 266 return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat &&
296 pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; 267 pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat;
diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h
index ec8efa210..e0ec1be0e 100644
--- a/src/video_core/texture_cache/surface_params.h
+++ b/src/video_core/texture_cache/surface_params.h
@@ -10,8 +10,9 @@
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "video_core/engines/fermi_2d.h" 11#include "video_core/engines/fermi_2d.h"
12#include "video_core/engines/maxwell_3d.h" 12#include "video_core/engines/maxwell_3d.h"
13#include "video_core/surface.h"
14#include "video_core/shader/shader_ir.h" 13#include "video_core/shader/shader_ir.h"
14#include "video_core/surface.h"
15#include "video_core/textures/decoders.h"
15 16
16namespace VideoCommon { 17namespace VideoCommon {
17 18
@@ -50,10 +51,17 @@ public:
50 std::size_t GetHostSizeInBytes() const { 51 std::size_t GetHostSizeInBytes() const {
51 std::size_t host_size_in_bytes; 52 std::size_t host_size_in_bytes;
52 if (IsPixelFormatASTC(pixel_format)) { 53 if (IsPixelFormatASTC(pixel_format)) {
54 constexpr std::size_t rgb8_bpp = 4ULL;
53 // ASTC is uncompressed in software, in emulated as RGBA8 55 // ASTC is uncompressed in software, in emulated as RGBA8
54 host_size_in_bytes = static_cast<std::size_t>(Common::AlignUp(width, GetDefaultBlockWidth())) * 56 host_size_in_bytes = 0;
55 static_cast<std::size_t>(Common::AlignUp(height, GetDefaultBlockHeight())) * 57 for (std::size_t level = 0; level < num_levels; level++) {
56 static_cast<std::size_t>(depth) * 4ULL; 58 const std::size_t width =
59 Common::AlignUp(GetMipWidth(level), GetDefaultBlockWidth());
60 const std::size_t height =
61 Common::AlignUp(GetMipHeight(level), GetDefaultBlockHeight());
62 const std::size_t depth = is_layered ? depth : GetMipDepth(level);
63 host_size_in_bytes += width * height * depth * rgb8_bpp;
64 }
57 } else { 65 } else {
58 host_size_in_bytes = GetInnerMemorySize(true, false, false); 66 host_size_in_bytes = GetInnerMemorySize(true, false, false);
59 } 67 }
@@ -65,13 +73,19 @@ public:
65 } 73 }
66 74
67 /// Returns the width of a given mipmap level. 75 /// Returns the width of a given mipmap level.
68 u32 GetMipWidth(u32 level) const; 76 u32 GetMipWidth(u32 level) const {
77 return std::max(1U, width >> level);
78 }
69 79
70 /// Returns the height of a given mipmap level. 80 /// Returns the height of a given mipmap level.
71 u32 GetMipHeight(u32 level) const; 81 u32 GetMipHeight(u32 level) const {
82 return std::max(1U, height >> level);
83 }
72 84
73 /// Returns the depth of a given mipmap level. 85 /// Returns the depth of a given mipmap level.
74 u32 GetMipDepth(u32 level) const; 86 u32 GetMipDepth(u32 level) const {
87 return is_layered ? depth : std::max(1U, depth >> level);
88 }
75 89
76 /// Returns the block height of a given mipmap level. 90 /// Returns the block height of a given mipmap level.
77 u32 GetMipBlockHeight(u32 level) const; 91 u32 GetMipBlockHeight(u32 level) const;
@@ -79,6 +93,12 @@ public:
79 /// Returns the block depth of a given mipmap level. 93 /// Returns the block depth of a given mipmap level.
80 u32 GetMipBlockDepth(u32 level) const; 94 u32 GetMipBlockDepth(u32 level) const;
81 95
96 // Helper used for out of class size calculations
97 static std::size_t AlignLayered(const std::size_t out_size, const u32 block_height,
98 const u32 block_depth) {
99 return Common::AlignUp(out_size, Tegra::Texture::GetGOBSize() * block_height * block_depth);
100 }
101
82 /// Returns the offset in bytes in guest memory of a given mipmap level. 102 /// Returns the offset in bytes in guest memory of a given mipmap level.
83 std::size_t GetGuestMipmapLevelOffset(u32 level) const; 103 std::size_t GetGuestMipmapLevelOffset(u32 level) const;
84 104
@@ -98,16 +118,24 @@ public:
98 std::size_t GetHostLayerSize(u32 level) const; 118 std::size_t GetHostLayerSize(u32 level) const;
99 119
100 /// Returns the default block width. 120 /// Returns the default block width.
101 u32 GetDefaultBlockWidth() const; 121 u32 GetDefaultBlockWidth() const {
122 return VideoCore::Surface::GetDefaultBlockWidth(pixel_format);
123 }
102 124
103 /// Returns the default block height. 125 /// Returns the default block height.
104 u32 GetDefaultBlockHeight() const; 126 u32 GetDefaultBlockHeight() const {
127 return VideoCore::Surface::GetDefaultBlockHeight(pixel_format);
128 }
105 129
106 /// Returns the bits per pixel. 130 /// Returns the bits per pixel.
107 u32 GetBitsPerPixel() const; 131 u32 GetBitsPerPixel() const {
132 return VideoCore::Surface::GetFormatBpp(pixel_format);
133 }
108 134
109 /// Returns the bytes per pixel. 135 /// Returns the bytes per pixel.
110 u32 GetBytesPerPixel() const; 136 u32 GetBytesPerPixel() const {
137 return VideoCore::Surface::GetBytesPerPixel(pixel_format);
138 }
111 139
112 /// Returns true if the pixel format is a depth and/or stencil format. 140 /// Returns true if the pixel format is a depth and/or stencil format.
113 bool IsPixelFormatZeta() const; 141 bool IsPixelFormatZeta() const;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 96d108147..fbfd1ff0b 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -120,10 +120,6 @@ public:
120 return {}; 120 return {};
121 } 121 }
122 122
123 if (regs.color_mask[index].raw == 0) {
124 return {};
125 }
126
127 auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index), 123 auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index),
128 preserve_contents); 124 preserve_contents);
129 if (render_targets[index].target) 125 if (render_targets[index].target)
@@ -165,7 +161,9 @@ public:
165 const Tegra::Engines::Fermi2D::Regs::Surface& dst_config, 161 const Tegra::Engines::Fermi2D::Regs::Surface& dst_config,
166 const Common::Rectangle<u32>& src_rect, 162 const Common::Rectangle<u32>& src_rect,
167 const Common::Rectangle<u32>& dst_rect) { 163 const Common::Rectangle<u32>& dst_rect) {
168 ImageBlit(GetFermiSurface(src_config), GetFermiSurface(dst_config), src_rect, dst_rect); 164 TSurface dst_surface = GetFermiSurface(dst_config);
165 ImageBlit(GetFermiSurface(src_config), dst_surface, src_rect, dst_rect);
166 dst_surface->MarkAsModified(true, Tick());
169 } 167 }
170 168
171 TSurface TryFindFramebufferSurface(const u8* host_ptr) { 169 TSurface TryFindFramebufferSurface(const u8* host_ptr) {
@@ -270,10 +268,6 @@ private:
270 268
271 RecycleStrategy PickStrategy(std::vector<TSurface>& overlaps, const SurfaceParams& params, 269 RecycleStrategy PickStrategy(std::vector<TSurface>& overlaps, const SurfaceParams& params,
272 const GPUVAddr gpu_addr, const bool untopological) { 270 const GPUVAddr gpu_addr, const bool untopological) {
273 // Untopological decision
274 if (untopological) {
275 return RecycleStrategy::Ignore;
276 }
277 // 3D Textures decision 271 // 3D Textures decision
278 if (params.block_depth > 1 || params.target == SurfaceTarget::Texture3D) { 272 if (params.block_depth > 1 || params.target == SurfaceTarget::Texture3D) {
279 return RecycleStrategy::Flush; 273 return RecycleStrategy::Flush;
@@ -284,12 +278,16 @@ private:
284 return RecycleStrategy::Flush; 278 return RecycleStrategy::Flush;
285 } 279 }
286 } 280 }
281 // Untopological decision
282 if (untopological) {
283 return RecycleStrategy::Ignore;
284 }
287 return RecycleStrategy::Ignore; 285 return RecycleStrategy::Ignore;
288 } 286 }
289 287
290 std::pair<TSurface, TView> RecycleSurface(std::vector<TSurface>& overlaps, 288 std::pair<TSurface, TView> RecycleSurface(std::vector<TSurface>& overlaps,
291 const SurfaceParams& params, const GPUVAddr gpu_addr, 289 const SurfaceParams& params, const GPUVAddr gpu_addr,
292 const u8* host_ptr, const bool preserve_contents, 290 const bool preserve_contents,
293 const bool untopological) { 291 const bool untopological) {
294 for (auto surface : overlaps) { 292 for (auto surface : overlaps) {
295 Unregister(surface); 293 Unregister(surface);
@@ -328,6 +326,7 @@ private:
328 } 326 }
329 Unregister(current_surface); 327 Unregister(current_surface);
330 Register(new_surface); 328 Register(new_surface);
329 new_surface->MarkAsModified(current_surface->IsModified(), Tick());
331 return {new_surface, new_surface->GetMainView()}; 330 return {new_surface, new_surface->GetMainView()};
332 } 331 }
333 332
@@ -351,6 +350,7 @@ private:
351 if (params.target == SurfaceTarget::Texture3D) { 350 if (params.target == SurfaceTarget::Texture3D) {
352 return {}; 351 return {};
353 } 352 }
353 bool modified = false;
354 TSurface new_surface = GetUncachedSurface(gpu_addr, params); 354 TSurface new_surface = GetUncachedSurface(gpu_addr, params);
355 for (auto surface : overlaps) { 355 for (auto surface : overlaps) {
356 const SurfaceParams& src_params = surface->GetSurfaceParams(); 356 const SurfaceParams& src_params = surface->GetSurfaceParams();
@@ -358,7 +358,7 @@ private:
358 // We send this cases to recycle as they are more complex to handle 358 // We send this cases to recycle as they are more complex to handle
359 return {}; 359 return {};
360 } 360 }
361 const std::size_t candidate_size = src_params.GetGuestSizeInBytes(); 361 const std::size_t candidate_size = surface->GetSizeInBytes();
362 auto mipmap_layer{new_surface->GetLayerMipmap(surface->GetGpuAddr())}; 362 auto mipmap_layer{new_surface->GetLayerMipmap(surface->GetGpuAddr())};
363 if (!mipmap_layer) { 363 if (!mipmap_layer) {
364 return {}; 364 return {};
@@ -368,6 +368,7 @@ private:
368 if (new_surface->GetMipmapSize(mipmap) != candidate_size) { 368 if (new_surface->GetMipmapSize(mipmap) != candidate_size) {
369 return {}; 369 return {};
370 } 370 }
371 modified |= surface->IsModified();
371 // Now we got all the data set up 372 // Now we got all the data set up
372 const u32 dst_width{params.GetMipWidth(mipmap)}; 373 const u32 dst_width{params.GetMipWidth(mipmap)};
373 const u32 dst_height{params.GetMipHeight(mipmap)}; 374 const u32 dst_height{params.GetMipHeight(mipmap)};
@@ -381,6 +382,7 @@ private:
381 force_reconfiguration |= surface->IsProtected(); 382 force_reconfiguration |= surface->IsProtected();
382 Unregister(surface, true); 383 Unregister(surface, true);
383 } 384 }
385 new_surface->MarkAsModified(modified, Tick());
384 Register(new_surface); 386 Register(new_surface);
385 return {{new_surface, new_surface->GetMainView()}}; 387 return {{new_surface, new_surface->GetMainView()}};
386 } 388 }
@@ -399,8 +401,7 @@ private:
399 401
400 for (auto surface : overlaps) { 402 for (auto surface : overlaps) {
401 if (!surface->MatchesTopology(params)) { 403 if (!surface->MatchesTopology(params)) {
402 return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, 404 return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, true);
403 true);
404 } 405 }
405 } 406 }
406 407
@@ -418,27 +419,26 @@ private:
418 } 419 }
419 } 420 }
420 if (!current_surface->IsInside(gpu_addr, gpu_addr + candidate_size)) { 421 if (!current_surface->IsInside(gpu_addr, gpu_addr + candidate_size)) {
421 return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, 422 return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false);
422 false);
423 } 423 }
424 std::optional<TView> view = current_surface->EmplaceView(params, gpu_addr); 424 std::optional<TView> view =
425 current_surface->EmplaceView(params, gpu_addr, candidate_size);
425 if (view.has_value()) { 426 if (view.has_value()) {
426 const bool is_mirage = !current_surface->MatchFormat(params.pixel_format); 427 const bool is_mirage = !current_surface->MatchFormat(params.pixel_format);
427 if (is_mirage) { 428 if (is_mirage) {
428 LOG_CRITICAL(HW_GPU, "Mirage View Unsupported"); 429 LOG_CRITICAL(HW_GPU, "Mirage View Unsupported");
429 return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, 430 return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false);
430 false);
431 } 431 }
432 return {current_surface, *view}; 432 return {current_surface, *view};
433 } 433 }
434 return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, false); 434 return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false);
435 } else { 435 } else {
436 std::optional<std::pair<TSurface, TView>> view = 436 std::optional<std::pair<TSurface, TView>> view =
437 ReconstructSurface(overlaps, params, gpu_addr, host_ptr); 437 ReconstructSurface(overlaps, params, gpu_addr, host_ptr);
438 if (view.has_value()) { 438 if (view.has_value()) {
439 return *view; 439 return *view;
440 } 440 }
441 return RecycleSurface(overlaps, params, gpu_addr, host_ptr, preserve_contents, false); 441 return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false);
442 } 442 }
443 } 443 }
444 444