summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/CMakeLists.txt3
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h2
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache_base.cpp10
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache_base.cpp10
-rw-r--r--src/video_core/texture_cache/image_view_info.cpp4
-rw-r--r--src/video_core/texture_cache/texture_cache.h419
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h385
13 files changed, 420 insertions, 427 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 1eb67c051..2f6cdd216 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -97,6 +97,7 @@ add_library(video_core STATIC
97 renderer_opengl/gl_stream_buffer.h 97 renderer_opengl/gl_stream_buffer.h
98 renderer_opengl/gl_texture_cache.cpp 98 renderer_opengl/gl_texture_cache.cpp
99 renderer_opengl/gl_texture_cache.h 99 renderer_opengl/gl_texture_cache.h
100 renderer_opengl/gl_texture_cache_base.cpp
100 renderer_opengl/gl_query_cache.cpp 101 renderer_opengl/gl_query_cache.cpp
101 renderer_opengl/gl_query_cache.h 102 renderer_opengl/gl_query_cache.h
102 renderer_opengl/maxwell_to_gl.h 103 renderer_opengl/maxwell_to_gl.h
@@ -155,6 +156,7 @@ add_library(video_core STATIC
155 renderer_vulkan/vk_swapchain.h 156 renderer_vulkan/vk_swapchain.h
156 renderer_vulkan/vk_texture_cache.cpp 157 renderer_vulkan/vk_texture_cache.cpp
157 renderer_vulkan/vk_texture_cache.h 158 renderer_vulkan/vk_texture_cache.h
159 renderer_vulkan/vk_texture_cache_base.cpp
158 renderer_vulkan/vk_update_descriptor.cpp 160 renderer_vulkan/vk_update_descriptor.cpp
159 renderer_vulkan/vk_update_descriptor.h 161 renderer_vulkan/vk_update_descriptor.h
160 shader_cache.cpp 162 shader_cache.cpp
@@ -186,6 +188,7 @@ add_library(video_core STATIC
186 texture_cache/samples_helper.h 188 texture_cache/samples_helper.h
187 texture_cache/slot_vector.h 189 texture_cache/slot_vector.h
188 texture_cache/texture_cache.h 190 texture_cache/texture_cache.h
191 texture_cache/texture_cache_base.h
189 texture_cache/types.h 192 texture_cache/types.h
190 texture_cache/util.cpp 193 texture_cache/util.cpp
191 texture_cache/util.h 194 texture_cache/util.h
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index fac0034fb..bccb37a58 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -15,7 +15,7 @@
15#include "video_core/renderer_opengl/gl_shader_util.h" 15#include "video_core/renderer_opengl/gl_shader_util.h"
16#include "video_core/renderer_opengl/gl_state_tracker.h" 16#include "video_core/renderer_opengl/gl_state_tracker.h"
17#include "video_core/shader_notify.h" 17#include "video_core/shader_notify.h"
18#include "video_core/texture_cache/texture_cache.h" 18#include "video_core/texture_cache/texture_cache_base.h"
19 19
20#if defined(_MSC_VER) && defined(NDEBUG) 20#if defined(_MSC_VER) && defined(NDEBUG)
21#define LAMBDA_FORCEINLINE [[msvc::forceinline]] 21#define LAMBDA_FORCEINLINE [[msvc::forceinline]]
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 41d2b73f4..b909c387e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -32,7 +32,7 @@
32#include "video_core/renderer_opengl/maxwell_to_gl.h" 32#include "video_core/renderer_opengl/maxwell_to_gl.h"
33#include "video_core/renderer_opengl/renderer_opengl.h" 33#include "video_core/renderer_opengl/renderer_opengl.h"
34#include "video_core/shader_cache.h" 34#include "video_core/shader_cache.h"
35#include "video_core/texture_cache/texture_cache.h" 35#include "video_core/texture_cache/texture_cache_base.h"
36 36
37namespace OpenGL { 37namespace OpenGL {
38 38
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index c373c9cb4..b0aee6cc1 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -18,10 +18,8 @@
18#include "video_core/renderer_opengl/maxwell_to_gl.h" 18#include "video_core/renderer_opengl/maxwell_to_gl.h"
19#include "video_core/renderer_opengl/util_shaders.h" 19#include "video_core/renderer_opengl/util_shaders.h"
20#include "video_core/surface.h" 20#include "video_core/surface.h"
21#include "video_core/texture_cache/format_lookup_table.h" 21#include "video_core/texture_cache/formatter.h"
22#include "video_core/texture_cache/samples_helper.h" 22#include "video_core/texture_cache/samples_helper.h"
23#include "video_core/texture_cache/texture_cache.h"
24#include "video_core/textures/decoders.h"
25 23
26namespace OpenGL { 24namespace OpenGL {
27namespace { 25namespace {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 921072ebe..4a4f6301c 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -12,7 +12,7 @@
12#include "shader_recompiler/shader_info.h" 12#include "shader_recompiler/shader_info.h"
13#include "video_core/renderer_opengl/gl_resource_manager.h" 13#include "video_core/renderer_opengl/gl_resource_manager.h"
14#include "video_core/renderer_opengl/util_shaders.h" 14#include "video_core/renderer_opengl/util_shaders.h"
15#include "video_core/texture_cache/texture_cache.h" 15#include "video_core/texture_cache/texture_cache_base.h"
16 16
17namespace OpenGL { 17namespace OpenGL {
18 18
diff --git a/src/video_core/renderer_opengl/gl_texture_cache_base.cpp b/src/video_core/renderer_opengl/gl_texture_cache_base.cpp
new file mode 100644
index 000000000..385358fea
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_texture_cache_base.cpp
@@ -0,0 +1,10 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "video_core/renderer_opengl/gl_texture_cache.h"
6#include "video_core/texture_cache/texture_cache.h"
7
8namespace VideoCommon {
9template class VideoCommon::TextureCache<OpenGL::TextureCacheParams>;
10}
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 23cef2996..3ac18ea54 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -32,7 +32,7 @@
32#include "video_core/renderer_vulkan/vk_texture_cache.h" 32#include "video_core/renderer_vulkan/vk_texture_cache.h"
33#include "video_core/renderer_vulkan/vk_update_descriptor.h" 33#include "video_core/renderer_vulkan/vk_update_descriptor.h"
34#include "video_core/shader_cache.h" 34#include "video_core/shader_cache.h"
35#include "video_core/texture_cache/texture_cache.h" 35#include "video_core/texture_cache/texture_cache_base.h"
36#include "video_core/vulkan_common/vulkan_device.h" 36#include "video_core/vulkan_common/vulkan_device.h"
37#include "video_core/vulkan_common/vulkan_wrapper.h" 37#include "video_core/vulkan_common/vulkan_wrapper.h"
38 38
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 8e029bcb3..8f4df7122 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -19,6 +19,8 @@
19#include "video_core/renderer_vulkan/vk_scheduler.h" 19#include "video_core/renderer_vulkan/vk_scheduler.h"
20#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" 20#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
21#include "video_core/renderer_vulkan/vk_texture_cache.h" 21#include "video_core/renderer_vulkan/vk_texture_cache.h"
22#include "video_core/texture_cache/formatter.h"
23#include "video_core/texture_cache/samples_helper.h"
22#include "video_core/vulkan_common/vulkan_device.h" 24#include "video_core/vulkan_common/vulkan_device.h"
23#include "video_core/vulkan_common/vulkan_memory_allocator.h" 25#include "video_core/vulkan_common/vulkan_memory_allocator.h"
24#include "video_core/vulkan_common/vulkan_wrapper.h" 26#include "video_core/vulkan_common/vulkan_wrapper.h"
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 0b73d55f8..5fe6b7ba3 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -9,7 +9,7 @@
9 9
10#include "shader_recompiler/shader_info.h" 10#include "shader_recompiler/shader_info.h"
11#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" 11#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
12#include "video_core/texture_cache/texture_cache.h" 12#include "video_core/texture_cache/texture_cache_base.h"
13#include "video_core/vulkan_common/vulkan_memory_allocator.h" 13#include "video_core/vulkan_common/vulkan_memory_allocator.h"
14#include "video_core/vulkan_common/vulkan_wrapper.h" 14#include "video_core/vulkan_common/vulkan_wrapper.h"
15 15
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache_base.cpp b/src/video_core/renderer_vulkan/vk_texture_cache_base.cpp
new file mode 100644
index 000000000..44e688342
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_texture_cache_base.cpp
@@ -0,0 +1,10 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "video_core/renderer_vulkan/vk_texture_cache.h"
6#include "video_core/texture_cache/texture_cache.h"
7
8namespace VideoCommon {
9template class VideoCommon::TextureCache<Vulkan::TextureCacheParams>;
10}
diff --git a/src/video_core/texture_cache/image_view_info.cpp b/src/video_core/texture_cache/image_view_info.cpp
index faf5b151f..6527e14c8 100644
--- a/src/video_core/texture_cache/image_view_info.cpp
+++ b/src/video_core/texture_cache/image_view_info.cpp
@@ -6,7 +6,7 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "video_core/texture_cache/image_view_info.h" 8#include "video_core/texture_cache/image_view_info.h"
9#include "video_core/texture_cache/texture_cache.h" 9#include "video_core/texture_cache/texture_cache_base.h"
10#include "video_core/texture_cache/types.h" 10#include "video_core/texture_cache/types.h"
11#include "video_core/textures/texture.h" 11#include "video_core/textures/texture.h"
12 12
@@ -14,6 +14,8 @@ namespace VideoCommon {
14 14
15namespace { 15namespace {
16 16
17using Tegra::Texture::TextureType;
18
17constexpr u8 RENDER_TARGET_SWIZZLE = std::numeric_limits<u8>::max(); 19constexpr u8 RENDER_TARGET_SWIZZLE = std::numeric_limits<u8>::max();
18 20
19[[nodiscard]] u8 CastSwizzle(SwizzleSource source) { 21[[nodiscard]] u8 CastSwizzle(SwizzleSource source) {
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index f34c9d9ca..a087498ff 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -4,48 +4,11 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <algorithm>
8#include <array>
9#include <bit>
10#include <memory>
11#include <mutex>
12#include <optional>
13#include <span>
14#include <type_traits>
15#include <unordered_map>
16#include <unordered_set>
17#include <utility>
18#include <vector>
19
20#include <boost/container/small_vector.hpp>
21
22#include "common/alignment.h" 7#include "common/alignment.h"
23#include "common/common_types.h"
24#include "common/literals.h"
25#include "common/logging/log.h"
26#include "common/settings.h" 8#include "common/settings.h"
27#include "video_core/compatible_formats.h"
28#include "video_core/delayed_destruction_ring.h"
29#include "video_core/dirty_flags.h" 9#include "video_core/dirty_flags.h"
30#include "video_core/engines/fermi_2d.h"
31#include "video_core/engines/kepler_compute.h"
32#include "video_core/engines/maxwell_3d.h"
33#include "video_core/memory_manager.h"
34#include "video_core/rasterizer_interface.h"
35#include "video_core/surface.h"
36#include "video_core/texture_cache/descriptor_table.h"
37#include "video_core/texture_cache/format_lookup_table.h"
38#include "video_core/texture_cache/formatter.h"
39#include "video_core/texture_cache/image_base.h"
40#include "video_core/texture_cache/image_info.h"
41#include "video_core/texture_cache/image_view_base.h"
42#include "video_core/texture_cache/image_view_info.h"
43#include "video_core/texture_cache/render_targets.h"
44#include "video_core/texture_cache/samples_helper.h" 10#include "video_core/texture_cache/samples_helper.h"
45#include "video_core/texture_cache/slot_vector.h" 11#include "video_core/texture_cache/texture_cache_base.h"
46#include "video_core/texture_cache/types.h"
47#include "video_core/texture_cache/util.h"
48#include "video_core/textures/texture.h"
49 12
50namespace VideoCommon { 13namespace VideoCommon {
51 14
@@ -62,352 +25,6 @@ using VideoCore::Surface::SurfaceType;
62using namespace Common::Literals; 25using namespace Common::Literals;
63 26
64template <class P> 27template <class P>
65class TextureCache {
66 /// Address shift for caching images into a hash table
67 static constexpr u64 PAGE_BITS = 20;
68
69 /// Enables debugging features to the texture cache
70 static constexpr bool ENABLE_VALIDATION = P::ENABLE_VALIDATION;
71 /// Implement blits as copies between framebuffers
72 static constexpr bool FRAMEBUFFER_BLITS = P::FRAMEBUFFER_BLITS;
73 /// True when some copies have to be emulated
74 static constexpr bool HAS_EMULATED_COPIES = P::HAS_EMULATED_COPIES;
75 /// True when the API can provide info about the memory of the device.
76 static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO;
77
78 /// Image view ID for null descriptors
79 static constexpr ImageViewId NULL_IMAGE_VIEW_ID{0};
80 /// Sampler ID for bugged sampler ids
81 static constexpr SamplerId NULL_SAMPLER_ID{0};
82
83 static constexpr u64 DEFAULT_EXPECTED_MEMORY = 1_GiB;
84 static constexpr u64 DEFAULT_CRITICAL_MEMORY = 2_GiB;
85
86 using Runtime = typename P::Runtime;
87 using Image = typename P::Image;
88 using ImageAlloc = typename P::ImageAlloc;
89 using ImageView = typename P::ImageView;
90 using Sampler = typename P::Sampler;
91 using Framebuffer = typename P::Framebuffer;
92
93 struct BlitImages {
94 ImageId dst_id;
95 ImageId src_id;
96 PixelFormat dst_format;
97 PixelFormat src_format;
98 };
99
100 template <typename T>
101 struct IdentityHash {
102 [[nodiscard]] size_t operator()(T value) const noexcept {
103 return static_cast<size_t>(value);
104 }
105 };
106
107public:
108 explicit TextureCache(Runtime&, VideoCore::RasterizerInterface&, Tegra::Engines::Maxwell3D&,
109 Tegra::Engines::KeplerCompute&, Tegra::MemoryManager&);
110
111 /// Notify the cache that a new frame has been queued
112 void TickFrame();
113
114 /// Return a constant reference to the given image view id
115 [[nodiscard]] const ImageView& GetImageView(ImageViewId id) const noexcept;
116
117 /// Return a reference to the given image view id
118 [[nodiscard]] ImageView& GetImageView(ImageViewId id) noexcept;
119
120 /// Mark an image as modified from the GPU
121 void MarkModification(ImageId id) noexcept;
122
123 /// Fill image_view_ids with the graphics images in indices
124 void FillGraphicsImageViews(std::span<const u32> indices,
125 std::span<ImageViewId> image_view_ids);
126
127 /// Fill image_view_ids with the compute images in indices
128 void FillComputeImageViews(std::span<const u32> indices, std::span<ImageViewId> image_view_ids);
129
130 /// Get the sampler from the graphics descriptor table in the specified index
131 Sampler* GetGraphicsSampler(u32 index);
132
133 /// Get the sampler from the compute descriptor table in the specified index
134 Sampler* GetComputeSampler(u32 index);
135
136 /// Refresh the state for graphics image view and sampler descriptors
137 void SynchronizeGraphicsDescriptors();
138
139 /// Refresh the state for compute image view and sampler descriptors
140 void SynchronizeComputeDescriptors();
141
142 /// Update bound render targets and upload memory if necessary
143 /// @param is_clear True when the render targets are being used for clears
144 void UpdateRenderTargets(bool is_clear);
145
146 /// Find a framebuffer with the currently bound render targets
147 /// UpdateRenderTargets should be called before this
148 Framebuffer* GetFramebuffer();
149
150 /// Mark images in a range as modified from the CPU
151 void WriteMemory(VAddr cpu_addr, size_t size);
152
153 /// Download contents of host images to guest memory in a region
154 void DownloadMemory(VAddr cpu_addr, size_t size);
155
156 /// Remove images in a region
157 void UnmapMemory(VAddr cpu_addr, size_t size);
158
159 /// Remove images in a region
160 void UnmapGPUMemory(GPUVAddr gpu_addr, size_t size);
161
162 /// Blit an image with the given parameters
163 void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
164 const Tegra::Engines::Fermi2D::Surface& src,
165 const Tegra::Engines::Fermi2D::Config& copy);
166
167 /// Invalidate the contents of the color buffer index
168 /// These contents become unspecified, the cache can assume aggressive optimizations.
169 void InvalidateColorBuffer(size_t index);
170
171 /// Invalidate the contents of the depth buffer
172 /// These contents become unspecified, the cache can assume aggressive optimizations.
173 void InvalidateDepthBuffer();
174
175 /// Try to find a cached image view in the given CPU address
176 [[nodiscard]] ImageView* TryFindFramebufferImageView(VAddr cpu_addr);
177
178 /// Return true when there are uncommitted images to be downloaded
179 [[nodiscard]] bool HasUncommittedFlushes() const noexcept;
180
181 /// Return true when the caller should wait for async downloads
182 [[nodiscard]] bool ShouldWaitAsyncFlushes() const noexcept;
183
184 /// Commit asynchronous downloads
185 void CommitAsyncFlushes();
186
187 /// Pop asynchronous downloads
188 void PopAsyncFlushes();
189
190 /// Return true when a CPU region is modified from the GPU
191 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size);
192
193 std::mutex mutex;
194
195private:
196 /// Iterate over all page indices in a range
197 template <typename Func>
198 static void ForEachCPUPage(VAddr addr, size_t size, Func&& func) {
199 static constexpr bool RETURNS_BOOL = std::is_same_v<std::invoke_result<Func, u64>, bool>;
200 const u64 page_end = (addr + size - 1) >> PAGE_BITS;
201 for (u64 page = addr >> PAGE_BITS; page <= page_end; ++page) {
202 if constexpr (RETURNS_BOOL) {
203 if (func(page)) {
204 break;
205 }
206 } else {
207 func(page);
208 }
209 }
210 }
211
212 template <typename Func>
213 static void ForEachGPUPage(GPUVAddr addr, size_t size, Func&& func) {
214 static constexpr bool RETURNS_BOOL = std::is_same_v<std::invoke_result<Func, u64>, bool>;
215 const u64 page_end = (addr + size - 1) >> PAGE_BITS;
216 for (u64 page = addr >> PAGE_BITS; page <= page_end; ++page) {
217 if constexpr (RETURNS_BOOL) {
218 if (func(page)) {
219 break;
220 }
221 } else {
222 func(page);
223 }
224 }
225 }
226
227 /// Runs the Garbage Collector.
228 void RunGarbageCollector();
229
230 /// Fills image_view_ids in the image views in indices
231 void FillImageViews(DescriptorTable<TICEntry>& table,
232 std::span<ImageViewId> cached_image_view_ids, std::span<const u32> indices,
233 std::span<ImageViewId> image_view_ids);
234
235 /// Find or create an image view in the guest descriptor table
236 ImageViewId VisitImageView(DescriptorTable<TICEntry>& table,
237 std::span<ImageViewId> cached_image_view_ids, u32 index);
238
239 /// Find or create a framebuffer with the given render target parameters
240 FramebufferId GetFramebufferId(const RenderTargets& key);
241
242 /// Refresh the contents (pixel data) of an image
243 void RefreshContents(Image& image, ImageId image_id);
244
245 /// Upload data from guest to an image
246 template <typename StagingBuffer>
247 void UploadImageContents(Image& image, StagingBuffer& staging_buffer);
248
249 /// Find or create an image view from a guest descriptor
250 [[nodiscard]] ImageViewId FindImageView(const TICEntry& config);
251
252 /// Create a new image view from a guest descriptor
253 [[nodiscard]] ImageViewId CreateImageView(const TICEntry& config);
254
255 /// Find or create an image from the given parameters
256 [[nodiscard]] ImageId FindOrInsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
257 RelaxedOptions options = RelaxedOptions{});
258
259 /// Find an image from the given parameters
260 [[nodiscard]] ImageId FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
261 RelaxedOptions options);
262
263 /// Create an image from the given parameters
264 [[nodiscard]] ImageId InsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
265 RelaxedOptions options);
266
267 /// Create a new image and join perfectly matching existing images
268 /// Remove joined images from the cache
269 [[nodiscard]] ImageId JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr);
270
271 /// Return a blit image pair from the given guest blit parameters
272 [[nodiscard]] BlitImages GetBlitImages(const Tegra::Engines::Fermi2D::Surface& dst,
273 const Tegra::Engines::Fermi2D::Surface& src);
274
275 /// Find or create a sampler from a guest descriptor sampler
276 [[nodiscard]] SamplerId FindSampler(const TSCEntry& config);
277
278 /// Find or create an image view for the given color buffer index
279 [[nodiscard]] ImageViewId FindColorBuffer(size_t index, bool is_clear);
280
281 /// Find or create an image view for the depth buffer
282 [[nodiscard]] ImageViewId FindDepthBuffer(bool is_clear);
283
284 /// Find or create a view for a render target with the given image parameters
285 [[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr,
286 bool is_clear);
287
288 /// Iterates over all the images in a region calling func
289 template <typename Func>
290 void ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& func);
291
292 template <typename Func>
293 void ForEachImageInRegionGPU(GPUVAddr gpu_addr, size_t size, Func&& func);
294
295 template <typename Func>
296 void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func);
297
298 /// Iterates over all the images in a region calling func
299 template <typename Func>
300 void ForEachSparseSegment(ImageBase& image, Func&& func);
301
302 /// Find or create an image view in the given image with the passed parameters
303 [[nodiscard]] ImageViewId FindOrEmplaceImageView(ImageId image_id, const ImageViewInfo& info);
304
305 /// Register image in the page table
306 void RegisterImage(ImageId image);
307
308 /// Unregister image from the page table
309 void UnregisterImage(ImageId image);
310
311 /// Track CPU reads and writes for image
312 void TrackImage(ImageBase& image, ImageId image_id);
313
314 /// Stop tracking CPU reads and writes for image
315 void UntrackImage(ImageBase& image, ImageId image_id);
316
317 /// Delete image from the cache
318 void DeleteImage(ImageId image);
319
320 /// Remove image views references from the cache
321 void RemoveImageViewReferences(std::span<const ImageViewId> removed_views);
322
323 /// Remove framebuffers using the given image views from the cache
324 void RemoveFramebuffers(std::span<const ImageViewId> removed_views);
325
326 /// Mark an image as modified from the GPU
327 void MarkModification(ImageBase& image) noexcept;
328
329 /// Synchronize image aliases, copying data if needed
330 void SynchronizeAliases(ImageId image_id);
331
332 /// Prepare an image to be used
333 void PrepareImage(ImageId image_id, bool is_modification, bool invalidate);
334
335 /// Prepare an image view to be used
336 void PrepareImageView(ImageViewId image_view_id, bool is_modification, bool invalidate);
337
338 /// Execute copies from one image to the other, even if they are incompatible
339 void CopyImage(ImageId dst_id, ImageId src_id, std::span<const ImageCopy> copies);
340
341 /// Bind an image view as render target, downloading resources preemtively if needed
342 void BindRenderTarget(ImageViewId* old_id, ImageViewId new_id);
343
344 /// Create a render target from a given image and image view parameters
345 [[nodiscard]] std::pair<FramebufferId, ImageViewId> RenderTargetFromImage(
346 ImageId, const ImageViewInfo& view_info);
347
348 /// Returns true if the current clear parameters clear the whole image of a given image view
349 [[nodiscard]] bool IsFullClear(ImageViewId id);
350
351 Runtime& runtime;
352 VideoCore::RasterizerInterface& rasterizer;
353 Tegra::Engines::Maxwell3D& maxwell3d;
354 Tegra::Engines::KeplerCompute& kepler_compute;
355 Tegra::MemoryManager& gpu_memory;
356
357 DescriptorTable<TICEntry> graphics_image_table{gpu_memory};
358 DescriptorTable<TSCEntry> graphics_sampler_table{gpu_memory};
359 std::vector<SamplerId> graphics_sampler_ids;
360 std::vector<ImageViewId> graphics_image_view_ids;
361
362 DescriptorTable<TICEntry> compute_image_table{gpu_memory};
363 DescriptorTable<TSCEntry> compute_sampler_table{gpu_memory};
364 std::vector<SamplerId> compute_sampler_ids;
365 std::vector<ImageViewId> compute_image_view_ids;
366
367 RenderTargets render_targets;
368
369 std::unordered_map<TICEntry, ImageViewId> image_views;
370 std::unordered_map<TSCEntry, SamplerId> samplers;
371 std::unordered_map<RenderTargets, FramebufferId> framebuffers;
372
373 std::unordered_map<u64, std::vector<ImageMapId>, IdentityHash<u64>> page_table;
374 std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> gpu_page_table;
375 std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> sparse_page_table;
376
377 std::unordered_map<ImageId, std::vector<ImageViewId>> sparse_views;
378
379 VAddr virtual_invalid_space{};
380
381 bool has_deleted_images = false;
382 u64 total_used_memory = 0;
383 u64 minimum_memory;
384 u64 expected_memory;
385 u64 critical_memory;
386
387 SlotVector<Image> slot_images;
388 SlotVector<ImageMapView> slot_map_views;
389 SlotVector<ImageView> slot_image_views;
390 SlotVector<ImageAlloc> slot_image_allocs;
391 SlotVector<Sampler> slot_samplers;
392 SlotVector<Framebuffer> slot_framebuffers;
393
394 // TODO: This data structure is not optimal and it should be reworked
395 std::vector<ImageId> uncommitted_downloads;
396 std::queue<std::vector<ImageId>> committed_downloads;
397
398 static constexpr size_t TICKS_TO_DESTROY = 6;
399 DelayedDestructionRing<Image, TICKS_TO_DESTROY> sentenced_images;
400 DelayedDestructionRing<ImageView, TICKS_TO_DESTROY> sentenced_image_view;
401 DelayedDestructionRing<Framebuffer, TICKS_TO_DESTROY> sentenced_framebuffers;
402
403 std::unordered_map<GPUVAddr, ImageAllocId> image_allocs_table;
404
405 u64 modification_tick = 0;
406 u64 frame_tick = 0;
407 typename SlotVector<Image>::Iterator deletion_iterator;
408};
409
410template <class P>
411TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& rasterizer_, 28TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& rasterizer_,
412 Tegra::Engines::Maxwell3D& maxwell3d_, 29 Tegra::Engines::Maxwell3D& maxwell3d_,
413 Tegra::Engines::KeplerCompute& kepler_compute_, 30 Tegra::Engines::KeplerCompute& kepler_compute_,
@@ -821,40 +438,6 @@ void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
821} 438}
822 439
823template <class P> 440template <class P>
824void TextureCache<P>::InvalidateColorBuffer(size_t index) {
825 ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
826 color_buffer_id = FindColorBuffer(index, false);
827 if (!color_buffer_id) {
828 LOG_ERROR(HW_GPU, "Invalidating invalid color buffer in index={}", index);
829 return;
830 }
831 // When invalidating a color buffer, the old contents are no longer relevant
832 ImageView& color_buffer = slot_image_views[color_buffer_id];
833 Image& image = slot_images[color_buffer.image_id];
834 image.flags &= ~ImageFlagBits::CpuModified;
835 image.flags &= ~ImageFlagBits::GpuModified;
836
837 runtime.InvalidateColorBuffer(color_buffer, index);
838}
839
840template <class P>
841void TextureCache<P>::InvalidateDepthBuffer() {
842 ImageViewId& depth_buffer_id = render_targets.depth_buffer_id;
843 depth_buffer_id = FindDepthBuffer(false);
844 if (!depth_buffer_id) {
845 LOG_ERROR(HW_GPU, "Invalidating invalid depth buffer");
846 return;
847 }
848 // When invalidating the depth buffer, the old contents are no longer relevant
849 ImageBase& image = slot_images[slot_image_views[depth_buffer_id].image_id];
850 image.flags &= ~ImageFlagBits::CpuModified;
851 image.flags &= ~ImageFlagBits::GpuModified;
852
853 ImageView& depth_buffer = slot_image_views[depth_buffer_id];
854 runtime.InvalidateDepthBuffer(depth_buffer);
855}
856
857template <class P>
858typename P::ImageView* TextureCache<P>::TryFindFramebufferImageView(VAddr cpu_addr) { 441typename P::ImageView* TextureCache<P>::TryFindFramebufferImageView(VAddr cpu_addr) {
859 // TODO: Properly implement this 442 // TODO: Properly implement this
860 const auto it = page_table.find(cpu_addr >> PAGE_BITS); 443 const auto it = page_table.find(cpu_addr >> PAGE_BITS);
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
new file mode 100644
index 000000000..e4ae351cb
--- /dev/null
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -0,0 +1,385 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <mutex>
9#include <span>
10#include <type_traits>
11#include <unordered_map>
12#include <unordered_set>
13#include <vector>
14
15#include "common/common_types.h"
16#include "common/literals.h"
17#include "video_core/compatible_formats.h"
18#include "video_core/delayed_destruction_ring.h"
19#include "video_core/engines/fermi_2d.h"
20#include "video_core/engines/kepler_compute.h"
21#include "video_core/engines/maxwell_3d.h"
22#include "video_core/memory_manager.h"
23#include "video_core/rasterizer_interface.h"
24#include "video_core/surface.h"
25#include "video_core/texture_cache/descriptor_table.h"
26#include "video_core/texture_cache/image_base.h"
27#include "video_core/texture_cache/image_info.h"
28#include "video_core/texture_cache/image_view_info.h"
29#include "video_core/texture_cache/render_targets.h"
30#include "video_core/texture_cache/slot_vector.h"
31#include "video_core/texture_cache/types.h"
32#include "video_core/texture_cache/util.h"
33#include "video_core/textures/texture.h"
34
35namespace VideoCommon {
36
37using Tegra::Texture::SwizzleSource;
38using Tegra::Texture::TICEntry;
39using Tegra::Texture::TSCEntry;
40using VideoCore::Surface::GetFormatType;
41using VideoCore::Surface::IsCopyCompatible;
42using VideoCore::Surface::PixelFormat;
43using VideoCore::Surface::PixelFormatFromDepthFormat;
44using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
45using namespace Common::Literals;
46
47template <class P>
48class TextureCache {
49 /// Address shift for caching images into a hash table
50 static constexpr u64 PAGE_BITS = 20;
51
52 /// Enables debugging features to the texture cache
53 static constexpr bool ENABLE_VALIDATION = P::ENABLE_VALIDATION;
54 /// Implement blits as copies between framebuffers
55 static constexpr bool FRAMEBUFFER_BLITS = P::FRAMEBUFFER_BLITS;
56 /// True when some copies have to be emulated
57 static constexpr bool HAS_EMULATED_COPIES = P::HAS_EMULATED_COPIES;
58 /// True when the API can provide info about the memory of the device.
59 static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO;
60
61 /// Image view ID for null descriptors
62 static constexpr ImageViewId NULL_IMAGE_VIEW_ID{0};
63 /// Sampler ID for bugged sampler ids
64 static constexpr SamplerId NULL_SAMPLER_ID{0};
65
66 static constexpr u64 DEFAULT_EXPECTED_MEMORY = 1_GiB;
67 static constexpr u64 DEFAULT_CRITICAL_MEMORY = 2_GiB;
68
69 using Runtime = typename P::Runtime;
70 using Image = typename P::Image;
71 using ImageAlloc = typename P::ImageAlloc;
72 using ImageView = typename P::ImageView;
73 using Sampler = typename P::Sampler;
74 using Framebuffer = typename P::Framebuffer;
75
76 struct BlitImages {
77 ImageId dst_id;
78 ImageId src_id;
79 PixelFormat dst_format;
80 PixelFormat src_format;
81 };
82
83 template <typename T>
84 struct IdentityHash {
85 [[nodiscard]] size_t operator()(T value) const noexcept {
86 return static_cast<size_t>(value);
87 }
88 };
89
90public:
91 explicit TextureCache(Runtime&, VideoCore::RasterizerInterface&, Tegra::Engines::Maxwell3D&,
92 Tegra::Engines::KeplerCompute&, Tegra::MemoryManager&);
93
94 /// Notify the cache that a new frame has been queued
95 void TickFrame();
96
97 /// Return a constant reference to the given image view id
98 [[nodiscard]] const ImageView& GetImageView(ImageViewId id) const noexcept;
99
100 /// Return a reference to the given image view id
101 [[nodiscard]] ImageView& GetImageView(ImageViewId id) noexcept;
102
103 /// Mark an image as modified from the GPU
104 void MarkModification(ImageId id) noexcept;
105
106 /// Fill image_view_ids with the graphics images in indices
107 void FillGraphicsImageViews(std::span<const u32> indices,
108 std::span<ImageViewId> image_view_ids);
109
110 /// Fill image_view_ids with the compute images in indices
111 void FillComputeImageViews(std::span<const u32> indices, std::span<ImageViewId> image_view_ids);
112
113 /// Get the sampler from the graphics descriptor table in the specified index
114 Sampler* GetGraphicsSampler(u32 index);
115
116 /// Get the sampler from the compute descriptor table in the specified index
117 Sampler* GetComputeSampler(u32 index);
118
119 /// Refresh the state for graphics image view and sampler descriptors
120 void SynchronizeGraphicsDescriptors();
121
122 /// Refresh the state for compute image view and sampler descriptors
123 void SynchronizeComputeDescriptors();
124
125 /// Update bound render targets and upload memory if necessary
126 /// @param is_clear True when the render targets are being used for clears
127 void UpdateRenderTargets(bool is_clear);
128
129 /// Find a framebuffer with the currently bound render targets
130 /// UpdateRenderTargets should be called before this
131 Framebuffer* GetFramebuffer();
132
133 /// Mark images in a range as modified from the CPU
134 void WriteMemory(VAddr cpu_addr, size_t size);
135
136 /// Download contents of host images to guest memory in a region
137 void DownloadMemory(VAddr cpu_addr, size_t size);
138
139 /// Remove images in a region
140 void UnmapMemory(VAddr cpu_addr, size_t size);
141
142 /// Remove images in a region
143 void UnmapGPUMemory(GPUVAddr gpu_addr, size_t size);
144
145 /// Blit an image with the given parameters
146 void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
147 const Tegra::Engines::Fermi2D::Surface& src,
148 const Tegra::Engines::Fermi2D::Config& copy);
149
150 /// Try to find a cached image view in the given CPU address
151 [[nodiscard]] ImageView* TryFindFramebufferImageView(VAddr cpu_addr);
152
153 /// Return true when there are uncommitted images to be downloaded
154 [[nodiscard]] bool HasUncommittedFlushes() const noexcept;
155
156 /// Return true when the caller should wait for async downloads
157 [[nodiscard]] bool ShouldWaitAsyncFlushes() const noexcept;
158
159 /// Commit asynchronous downloads
160 void CommitAsyncFlushes();
161
162 /// Pop asynchronous downloads
163 void PopAsyncFlushes();
164
165 /// Return true when a CPU region is modified from the GPU
166 [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size);
167
168 std::mutex mutex;
169
170private:
171 /// Iterate over all page indices in a range
172 template <typename Func>
173 static void ForEachCPUPage(VAddr addr, size_t size, Func&& func) {
174 static constexpr bool RETURNS_BOOL = std::is_same_v<std::invoke_result<Func, u64>, bool>;
175 const u64 page_end = (addr + size - 1) >> PAGE_BITS;
176 for (u64 page = addr >> PAGE_BITS; page <= page_end; ++page) {
177 if constexpr (RETURNS_BOOL) {
178 if (func(page)) {
179 break;
180 }
181 } else {
182 func(page);
183 }
184 }
185 }
186
187 template <typename Func>
188 static void ForEachGPUPage(GPUVAddr addr, size_t size, Func&& func) {
189 static constexpr bool RETURNS_BOOL = std::is_same_v<std::invoke_result<Func, u64>, bool>;
190 const u64 page_end = (addr + size - 1) >> PAGE_BITS;
191 for (u64 page = addr >> PAGE_BITS; page <= page_end; ++page) {
192 if constexpr (RETURNS_BOOL) {
193 if (func(page)) {
194 break;
195 }
196 } else {
197 func(page);
198 }
199 }
200 }
201
202 /// Runs the Garbage Collector.
203 void RunGarbageCollector();
204
205 /// Fills image_view_ids in the image views in indices
206 void FillImageViews(DescriptorTable<TICEntry>& table,
207 std::span<ImageViewId> cached_image_view_ids, std::span<const u32> indices,
208 std::span<ImageViewId> image_view_ids);
209
210 /// Find or create an image view in the guest descriptor table
211 ImageViewId VisitImageView(DescriptorTable<TICEntry>& table,
212 std::span<ImageViewId> cached_image_view_ids, u32 index);
213
214 /// Find or create a framebuffer with the given render target parameters
215 FramebufferId GetFramebufferId(const RenderTargets& key);
216
217 /// Refresh the contents (pixel data) of an image
218 void RefreshContents(Image& image, ImageId image_id);
219
220 /// Upload data from guest to an image
221 template <typename StagingBuffer>
222 void UploadImageContents(Image& image, StagingBuffer& staging_buffer);
223
224 /// Find or create an image view from a guest descriptor
225 [[nodiscard]] ImageViewId FindImageView(const TICEntry& config);
226
227 /// Create a new image view from a guest descriptor
228 [[nodiscard]] ImageViewId CreateImageView(const TICEntry& config);
229
230 /// Find or create an image from the given parameters
231 [[nodiscard]] ImageId FindOrInsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
232 RelaxedOptions options = RelaxedOptions{});
233
234 /// Find an image from the given parameters
235 [[nodiscard]] ImageId FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
236 RelaxedOptions options);
237
238 /// Create an image from the given parameters
239 [[nodiscard]] ImageId InsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
240 RelaxedOptions options);
241
242 /// Create a new image and join perfectly matching existing images
243 /// Remove joined images from the cache
244 [[nodiscard]] ImageId JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr);
245
246 /// Return a blit image pair from the given guest blit parameters
247 [[nodiscard]] BlitImages GetBlitImages(const Tegra::Engines::Fermi2D::Surface& dst,
248 const Tegra::Engines::Fermi2D::Surface& src);
249
250 /// Find or create a sampler from a guest descriptor sampler
251 [[nodiscard]] SamplerId FindSampler(const TSCEntry& config);
252
253 /// Find or create an image view for the given color buffer index
254 [[nodiscard]] ImageViewId FindColorBuffer(size_t index, bool is_clear);
255
256 /// Find or create an image view for the depth buffer
257 [[nodiscard]] ImageViewId FindDepthBuffer(bool is_clear);
258
259 /// Find or create a view for a render target with the given image parameters
260 [[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr,
261 bool is_clear);
262
263 /// Iterates over all the images in a region calling func
264 template <typename Func>
265 void ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& func);
266
267 template <typename Func>
268 void ForEachImageInRegionGPU(GPUVAddr gpu_addr, size_t size, Func&& func);
269
270 template <typename Func>
271 void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func);
272
273 /// Iterates over all the images in a region calling func
274 template <typename Func>
275 void ForEachSparseSegment(ImageBase& image, Func&& func);
276
277 /// Find or create an image view in the given image with the passed parameters
278 [[nodiscard]] ImageViewId FindOrEmplaceImageView(ImageId image_id, const ImageViewInfo& info);
279
280 /// Register image in the page table
281 void RegisterImage(ImageId image);
282
283 /// Unregister image from the page table
284 void UnregisterImage(ImageId image);
285
286 /// Track CPU reads and writes for image
287 void TrackImage(ImageBase& image, ImageId image_id);
288
289 /// Stop tracking CPU reads and writes for image
290 void UntrackImage(ImageBase& image, ImageId image_id);
291
292 /// Delete image from the cache
293 void DeleteImage(ImageId image);
294
295 /// Remove image views references from the cache
296 void RemoveImageViewReferences(std::span<const ImageViewId> removed_views);
297
298 /// Remove framebuffers using the given image views from the cache
299 void RemoveFramebuffers(std::span<const ImageViewId> removed_views);
300
301 /// Mark an image as modified from the GPU
302 void MarkModification(ImageBase& image) noexcept;
303
304 /// Synchronize image aliases, copying data if needed
305 void SynchronizeAliases(ImageId image_id);
306
307 /// Prepare an image to be used
308 void PrepareImage(ImageId image_id, bool is_modification, bool invalidate);
309
310 /// Prepare an image view to be used
311 void PrepareImageView(ImageViewId image_view_id, bool is_modification, bool invalidate);
312
313 /// Execute copies from one image to the other, even if they are incompatible
314 void CopyImage(ImageId dst_id, ImageId src_id, std::span<const ImageCopy> copies);
315
316 /// Bind an image view as render target, downloading resources preemtively if needed
317 void BindRenderTarget(ImageViewId* old_id, ImageViewId new_id);
318
319 /// Create a render target from a given image and image view parameters
320 [[nodiscard]] std::pair<FramebufferId, ImageViewId> RenderTargetFromImage(
321 ImageId, const ImageViewInfo& view_info);
322
323 /// Returns true if the current clear parameters clear the whole image of a given image view
324 [[nodiscard]] bool IsFullClear(ImageViewId id);
325
326 Runtime& runtime;
327 VideoCore::RasterizerInterface& rasterizer;
328 Tegra::Engines::Maxwell3D& maxwell3d;
329 Tegra::Engines::KeplerCompute& kepler_compute;
330 Tegra::MemoryManager& gpu_memory;
331
332 DescriptorTable<TICEntry> graphics_image_table{gpu_memory};
333 DescriptorTable<TSCEntry> graphics_sampler_table{gpu_memory};
334 std::vector<SamplerId> graphics_sampler_ids;
335 std::vector<ImageViewId> graphics_image_view_ids;
336
337 DescriptorTable<TICEntry> compute_image_table{gpu_memory};
338 DescriptorTable<TSCEntry> compute_sampler_table{gpu_memory};
339 std::vector<SamplerId> compute_sampler_ids;
340 std::vector<ImageViewId> compute_image_view_ids;
341
342 RenderTargets render_targets;
343
344 std::unordered_map<TICEntry, ImageViewId> image_views;
345 std::unordered_map<TSCEntry, SamplerId> samplers;
346 std::unordered_map<RenderTargets, FramebufferId> framebuffers;
347
348 std::unordered_map<u64, std::vector<ImageMapId>, IdentityHash<u64>> page_table;
349 std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> gpu_page_table;
350 std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> sparse_page_table;
351
352 std::unordered_map<ImageId, std::vector<ImageViewId>> sparse_views;
353
354 VAddr virtual_invalid_space{};
355
356 bool has_deleted_images = false;
357 u64 total_used_memory = 0;
358 u64 minimum_memory;
359 u64 expected_memory;
360 u64 critical_memory;
361
362 SlotVector<Image> slot_images;
363 SlotVector<ImageMapView> slot_map_views;
364 SlotVector<ImageView> slot_image_views;
365 SlotVector<ImageAlloc> slot_image_allocs;
366 SlotVector<Sampler> slot_samplers;
367 SlotVector<Framebuffer> slot_framebuffers;
368
369 // TODO: This data structure is not optimal and it should be reworked
370 std::vector<ImageId> uncommitted_downloads;
371 std::queue<std::vector<ImageId>> committed_downloads;
372
373 static constexpr size_t TICKS_TO_DESTROY = 6;
374 DelayedDestructionRing<Image, TICKS_TO_DESTROY> sentenced_images;
375 DelayedDestructionRing<ImageView, TICKS_TO_DESTROY> sentenced_image_view;
376 DelayedDestructionRing<Framebuffer, TICKS_TO_DESTROY> sentenced_framebuffers;
377
378 std::unordered_map<GPUVAddr, ImageAllocId> image_allocs_table;
379
380 u64 modification_tick = 0;
381 u64 frame_tick = 0;
382 typename SlotVector<Image>::Iterator deletion_iterator;
383};
384
385} // namespace VideoCommon