summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-12-17 16:45:06 +0100
committerGravatar Fernando Sahmkow2022-10-06 21:00:52 +0200
commite462191482c6507daed67802c6c1d2c50f10c96e (patch)
treea6b4d851075d93b3052637d1382691e71b9b8c0e /src/video_core/texture_cache
parentGeneral: Rebase fixes. (diff)
downloadyuzu-e462191482c6507daed67802c6c1d2c50f10c96e.tar.gz
yuzu-e462191482c6507daed67802c6c1d2c50f10c96e.tar.xz
yuzu-e462191482c6507daed67802c6c1d2c50f10c96e.zip
Refactor VideoCore to use AS sepparate from Channel.
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/texture_cache.cpp16
-rw-r--r--src/video_core/texture_cache/texture_cache.h130
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h96
3 files changed, 101 insertions, 141 deletions
diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp
new file mode 100644
index 000000000..bc905a1a4
--- /dev/null
+++ b/src/video_core/texture_cache/texture_cache.cpp
@@ -0,0 +1,16 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv3 or any later version
3// Refer to the license.txt file included.
4
5#include "video_core/control/channel_state_cache.inc"
6#include "video_core/texture_cache/texture_cache_base.h"
7
8namespace VideoCommon {
9
10TextureCacheChannelInfo::TextureCacheChannelInfo(Tegra::Control::ChannelState& state) noexcept
11 : ChannelInfo(state), graphics_image_table{gpu_memory}, graphics_sampler_table{gpu_memory},
12 compute_image_table{gpu_memory}, compute_sampler_table{gpu_memory} {}
13
14template class VideoCommon::ChannelSetupCaches<VideoCommon::TextureCacheChannelInfo>;
15
16} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 0ec999d63..89c5faf88 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1,5 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project 1// SPDX-FileCopyrightText: 2021 yuzu emulator team
2// SPDX-License-Identifier: GPL-2.0-or-later 2// (https://github.com/skyline-emu/)
3// SPDX-License-Identifier: GPL-3.0-or-later Licensed under GPLv3
4// or any later version Refer to the license.txt file included.
3 5
4#pragma once 6#pragma once
5 7
@@ -41,10 +43,6 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
41 43
42 // Setup channels 44 // Setup channels
43 current_channel_id = UNSET_CHANNEL; 45 current_channel_id = UNSET_CHANNEL;
44 state = nullptr;
45 maxwell3d = nullptr;
46 kepler_compute = nullptr;
47 gpu_memory = nullptr;
48 46
49 // Make sure the first index is reserved for the null resources 47 // Make sure the first index is reserved for the null resources
50 // This way the null resource becomes a compile time constant 48 // This way the null resource becomes a compile time constant
@@ -156,23 +154,24 @@ void TextureCache<P>::MarkModification(ImageId id) noexcept {
156template <class P> 154template <class P>
157template <bool has_blacklists> 155template <bool has_blacklists>
158void TextureCache<P>::FillGraphicsImageViews(std::span<ImageViewInOut> views) { 156void TextureCache<P>::FillGraphicsImageViews(std::span<ImageViewInOut> views) {
159 FillImageViews<has_blacklists>(state->graphics_image_table, state->graphics_image_view_ids, 157 FillImageViews<has_blacklists>(channel_state->graphics_image_table,
160 views); 158 channel_state->graphics_image_view_ids, views);
161} 159}
162 160
163template <class P> 161template <class P>
164void TextureCache<P>::FillComputeImageViews(std::span<ImageViewInOut> views) { 162void TextureCache<P>::FillComputeImageViews(std::span<ImageViewInOut> views) {
165 FillImageViews<true>(state->compute_image_table, state->compute_image_view_ids, views); 163 FillImageViews<true>(channel_state->compute_image_table, channel_state->compute_image_view_ids,
164 views);
166} 165}
167 166
168template <class P> 167template <class P>
169typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) { 168typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) {
170 if (index > state->graphics_sampler_table.Limit()) { 169 if (index > channel_state->graphics_sampler_table.Limit()) {
171 LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index); 170 LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index);
172 return &slot_samplers[NULL_SAMPLER_ID]; 171 return &slot_samplers[NULL_SAMPLER_ID];
173 } 172 }
174 const auto [descriptor, is_new] = state->graphics_sampler_table.Read(index); 173 const auto [descriptor, is_new] = channel_state->graphics_sampler_table.Read(index);
175 SamplerId& id = state->graphics_sampler_ids[index]; 174 SamplerId& id = channel_state->graphics_sampler_ids[index];
176 if (is_new) { 175 if (is_new) {
177 id = FindSampler(descriptor); 176 id = FindSampler(descriptor);
178 } 177 }
@@ -181,12 +180,12 @@ typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) {
181 180
182template <class P> 181template <class P>
183typename P::Sampler* TextureCache<P>::GetComputeSampler(u32 index) { 182typename P::Sampler* TextureCache<P>::GetComputeSampler(u32 index) {
184 if (index > state->compute_sampler_table.Limit()) { 183 if (index > channel_state->compute_sampler_table.Limit()) {
185 LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index); 184 LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index);
186 return &slot_samplers[NULL_SAMPLER_ID]; 185 return &slot_samplers[NULL_SAMPLER_ID];
187 } 186 }
188 const auto [descriptor, is_new] = state->compute_sampler_table.Read(index); 187 const auto [descriptor, is_new] = channel_state->compute_sampler_table.Read(index);
189 SamplerId& id = state->compute_sampler_ids[index]; 188 SamplerId& id = channel_state->compute_sampler_ids[index];
190 if (is_new) { 189 if (is_new) {
191 id = FindSampler(descriptor); 190 id = FindSampler(descriptor);
192 } 191 }
@@ -199,11 +198,12 @@ void TextureCache<P>::SynchronizeGraphicsDescriptors() {
199 const bool linked_tsc = maxwell3d->regs.sampler_index == SamplerIndex::ViaHeaderIndex; 198 const bool linked_tsc = maxwell3d->regs.sampler_index == SamplerIndex::ViaHeaderIndex;
200 const u32 tic_limit = maxwell3d->regs.tic.limit; 199 const u32 tic_limit = maxwell3d->regs.tic.limit;
201 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tsc.limit; 200 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tsc.limit;
202 if (state->graphics_sampler_table.Synchornize(maxwell3d->regs.tsc.Address(), tsc_limit)) { 201 if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tsc.Address(),
203 state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); 202 tsc_limit)) {
203 channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
204 } 204 }
205 if (state->graphics_image_table.Synchornize(maxwell3d->regs.tic.Address(), tic_limit)) { 205 if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tic.Address(), tic_limit)) {
206 state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); 206 channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
207 } 207 }
208} 208}
209 209
@@ -213,11 +213,12 @@ void TextureCache<P>::SynchronizeComputeDescriptors() {
213 const u32 tic_limit = kepler_compute->regs.tic.limit; 213 const u32 tic_limit = kepler_compute->regs.tic.limit;
214 const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit; 214 const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit;
215 const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address(); 215 const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address();
216 if (state->compute_sampler_table.Synchornize(tsc_gpu_addr, tsc_limit)) { 216 if (channel_state->compute_sampler_table.Synchornize(tsc_gpu_addr, tsc_limit)) {
217 state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); 217 channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
218 } 218 }
219 if (state->compute_image_table.Synchornize(kepler_compute->regs.tic.Address(), tic_limit)) { 219 if (channel_state->compute_image_table.Synchornize(kepler_compute->regs.tic.Address(),
220 state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); 220 tic_limit)) {
221 channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
221 } 222 }
222} 223}
223 224
@@ -738,7 +739,7 @@ ImageViewId TextureCache<P>::FindImageView(const TICEntry& config) {
738 if (!IsValidEntry(*gpu_memory, config)) { 739 if (!IsValidEntry(*gpu_memory, config)) {
739 return NULL_IMAGE_VIEW_ID; 740 return NULL_IMAGE_VIEW_ID;
740 } 741 }
741 const auto [pair, is_new] = state->image_views.try_emplace(config); 742 const auto [pair, is_new] = channel_state->image_views.try_emplace(config);
742 ImageViewId& image_view_id = pair->second; 743 ImageViewId& image_view_id = pair->second;
743 if (is_new) { 744 if (is_new) {
744 image_view_id = CreateImageView(config); 745 image_view_id = CreateImageView(config);
@@ -1198,7 +1199,7 @@ SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) {
1198 if (std::ranges::all_of(config.raw, [](u64 value) { return value == 0; })) { 1199 if (std::ranges::all_of(config.raw, [](u64 value) { return value == 0; })) {
1199 return NULL_SAMPLER_ID; 1200 return NULL_SAMPLER_ID;
1200 } 1201 }
1201 const auto [pair, is_new] = state->samplers.try_emplace(config); 1202 const auto [pair, is_new] = channel_state->samplers.try_emplace(config);
1202 if (is_new) { 1203 if (is_new) {
1203 pair->second = slot_samplers.insert(runtime, config); 1204 pair->second = slot_samplers.insert(runtime, config);
1204 } 1205 }
@@ -1327,8 +1328,8 @@ void TextureCache<P>::ForEachImageInRegionGPU(GPUVAddr gpu_addr, size_t size, Fu
1327 static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>; 1328 static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
1328 boost::container::small_vector<ImageId, 8> images; 1329 boost::container::small_vector<ImageId, 8> images;
1329 ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) { 1330 ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) {
1330 const auto it = state->gpu_page_table.find(page); 1331 const auto it = channel_state->gpu_page_table->find(page);
1331 if (it == state->gpu_page_table.end()) { 1332 if (it == channel_state->gpu_page_table->end()) {
1332 if constexpr (BOOL_BREAK) { 1333 if constexpr (BOOL_BREAK) {
1333 return false; 1334 return false;
1334 } else { 1335 } else {
@@ -1454,8 +1455,9 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
1454 } 1455 }
1455 image.lru_index = lru_cache.Insert(image_id, frame_tick); 1456 image.lru_index = lru_cache.Insert(image_id, frame_tick);
1456 1457
1457 ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, 1458 ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
1458 [this, image_id](u64 page) { state->gpu_page_table[page].push_back(image_id); }); 1459 (*channel_state->gpu_page_table)[page].push_back(image_id);
1460 });
1459 if (False(image.flags & ImageFlagBits::Sparse)) { 1461 if (False(image.flags & ImageFlagBits::Sparse)) {
1460 auto map_id = 1462 auto map_id =
1461 slot_map_views.insert(image.gpu_addr, image.cpu_addr, image.guest_size_bytes, image_id); 1463 slot_map_views.insert(image.gpu_addr, image.cpu_addr, image.guest_size_bytes, image_id);
@@ -1486,9 +1488,9 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
1486 image.flags &= ~ImageFlagBits::BadOverlap; 1488 image.flags &= ~ImageFlagBits::BadOverlap;
1487 lru_cache.Free(image.lru_index); 1489 lru_cache.Free(image.lru_index);
1488 const auto& clear_page_table = 1490 const auto& clear_page_table =
1489 [this, image_id]( 1491 [this, image_id](u64 page,
1490 u64 page, 1492 std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>>&
1491 std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>>& selected_page_table) { 1493 selected_page_table) {
1492 const auto page_it = selected_page_table.find(page); 1494 const auto page_it = selected_page_table.find(page);
1493 if (page_it == selected_page_table.end()) { 1495 if (page_it == selected_page_table.end()) {
1494 ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << YUZU_PAGEBITS); 1496 ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << YUZU_PAGEBITS);
@@ -1504,7 +1506,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
1504 image_ids.erase(vector_it); 1506 image_ids.erase(vector_it);
1505 }; 1507 };
1506 ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) { 1508 ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) {
1507 clear_page_table(page, state->gpu_page_table); 1509 clear_page_table(page, (*channel_state->gpu_page_table));
1508 }); 1510 });
1509 if (False(image.flags & ImageFlagBits::Sparse)) { 1511 if (False(image.flags & ImageFlagBits::Sparse)) {
1510 const auto map_id = image.map_view_id; 1512 const auto map_id = image.map_view_id;
@@ -1701,11 +1703,11 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {
1701 1703
1702template <class P> 1704template <class P>
1703void TextureCache<P>::RemoveImageViewReferences(std::span<const ImageViewId> removed_views) { 1705void TextureCache<P>::RemoveImageViewReferences(std::span<const ImageViewId> removed_views) {
1704 auto it = state->image_views.begin(); 1706 auto it = channel_state->image_views.begin();
1705 while (it != state->image_views.end()) { 1707 while (it != channel_state->image_views.end()) {
1706 const auto found = std::ranges::find(removed_views, it->second); 1708 const auto found = std::ranges::find(removed_views, it->second);
1707 if (found != removed_views.end()) { 1709 if (found != removed_views.end()) {
1708 it = state->image_views.erase(it); 1710 it = channel_state->image_views.erase(it);
1709 } else { 1711 } else {
1710 ++it; 1712 ++it;
1711 } 1713 }
@@ -1968,60 +1970,18 @@ bool TextureCache<P>::IsFullClear(ImageViewId id) {
1968} 1970}
1969 1971
1970template <class P> 1972template <class P>
1971TextureCache<P>::ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& state) noexcept
1972 : maxwell3d{*state.maxwell_3d}, kepler_compute{*state.kepler_compute},
1973 gpu_memory{*state.memory_manager}, graphics_image_table{gpu_memory},
1974 graphics_sampler_table{gpu_memory}, compute_image_table{gpu_memory}, compute_sampler_table{
1975 gpu_memory} {}
1976
1977template <class P>
1978void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) { 1973void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) {
1979 ASSERT(channel_map.find(channel.bind_id) == channel_map.end() && channel.bind_id >= 0); 1974 VideoCommon::ChannelSetupCaches<TextureCacheChannelInfo>::CreateChannel(channel);
1980 auto new_id = [this, &channel]() { 1975 const auto it = channel_map.find(channel.bind_id);
1981 if (!free_channel_ids.empty()) { 1976 auto* this_state = &channel_storage[it->second];
1982 auto id = free_channel_ids.front(); 1977 const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()];
1983 free_channel_ids.pop_front(); 1978 this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id];
1984 new (&channel_storage[id]) ChannelInfo(channel);
1985 return id;
1986 }
1987 channel_storage.emplace_back(channel);
1988 return channel_storage.size() - 1;
1989 }();
1990 channel_map.emplace(channel.bind_id, new_id);
1991 if (current_channel_id != UNSET_CHANNEL) {
1992 state = &channel_storage[current_channel_id];
1993 }
1994} 1979}
1995 1980
1996/// Bind a channel for execution. 1981/// Bind a channel for execution.
1997template <class P> 1982template <class P>
1998void TextureCache<P>::BindToChannel(s32 id) { 1983void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) {
1999 auto it = channel_map.find(id); 1984 gpu_page_table_storage.emplace_back();
2000 ASSERT(it != channel_map.end() && id >= 0);
2001 current_channel_id = it->second;
2002 state = &channel_storage[current_channel_id];
2003 maxwell3d = &state->maxwell3d;
2004 kepler_compute = &state->kepler_compute;
2005 gpu_memory = &state->gpu_memory;
2006}
2007
2008/// Erase channel's state.
2009template <class P>
2010void TextureCache<P>::EraseChannel(s32 id) {
2011 const auto it = channel_map.find(id);
2012 ASSERT(it != channel_map.end() && id >= 0);
2013 const auto this_id = it->second;
2014 free_channel_ids.push_back(this_id);
2015 channel_map.erase(it);
2016 if (this_id == current_channel_id) {
2017 current_channel_id = UNSET_CHANNEL;
2018 state = nullptr;
2019 maxwell3d = nullptr;
2020 kepler_compute = nullptr;
2021 gpu_memory = nullptr;
2022 } else if (current_channel_id != UNSET_CHANNEL) {
2023 state = &channel_storage[current_channel_id];
2024 }
2025} 1985}
2026 1986
2027} // namespace VideoCommon 1987} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 69efcb718..b24968b03 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -1,5 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project 1// SPDX-FileCopyrightText: 2021 yuzu emulator team
2// SPDX-License-Identifier: GPL-2.0-or-later 2// (https://github.com/skyline-emu/)
3// SPDX-License-Identifier: GPL-3.0-or-later Licensed under GPLv3
4// or any later version Refer to the license.txt file included.
3 5
4#pragma once 6#pragma once
5 7
@@ -13,9 +15,11 @@
13#include <queue> 15#include <queue>
14 16
15#include "common/common_types.h" 17#include "common/common_types.h"
18#include "common/hash.h"
16#include "common/literals.h" 19#include "common/literals.h"
17#include "common/lru_cache.h" 20#include "common/lru_cache.h"
18#include "video_core/compatible_formats.h" 21#include "video_core/compatible_formats.h"
22#include "video_core/control/channel_state_cache.h"
19#include "video_core/delayed_destruction_ring.h" 23#include "video_core/delayed_destruction_ring.h"
20#include "video_core/engines/fermi_2d.h" 24#include "video_core/engines/fermi_2d.h"
21#include "video_core/surface.h" 25#include "video_core/surface.h"
@@ -50,8 +54,35 @@ struct ImageViewInOut {
50 ImageViewId id{}; 54 ImageViewId id{};
51}; 55};
52 56
57using TextureCacheGPUMap = std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>>;
58
59class TextureCacheChannelInfo : public ChannelInfo {
60public:
61 TextureCacheChannelInfo() = delete;
62 TextureCacheChannelInfo(Tegra::Control::ChannelState& state) noexcept;
63 TextureCacheChannelInfo(const TextureCacheChannelInfo& state) = delete;
64 TextureCacheChannelInfo& operator=(const TextureCacheChannelInfo&) = delete;
65 TextureCacheChannelInfo(TextureCacheChannelInfo&& other) noexcept = default;
66 TextureCacheChannelInfo& operator=(TextureCacheChannelInfo&& other) noexcept = default;
67
68 DescriptorTable<TICEntry> graphics_image_table{gpu_memory};
69 DescriptorTable<TSCEntry> graphics_sampler_table{gpu_memory};
70 std::vector<SamplerId> graphics_sampler_ids;
71 std::vector<ImageViewId> graphics_image_view_ids;
72
73 DescriptorTable<TICEntry> compute_image_table{gpu_memory};
74 DescriptorTable<TSCEntry> compute_sampler_table{gpu_memory};
75 std::vector<SamplerId> compute_sampler_ids;
76 std::vector<ImageViewId> compute_image_view_ids;
77
78 std::unordered_map<TICEntry, ImageViewId> image_views;
79 std::unordered_map<TSCEntry, SamplerId> samplers;
80
81 TextureCacheGPUMap* gpu_page_table;
82};
83
53template <class P> 84template <class P>
54class TextureCache { 85class TextureCache : public VideoCommon::ChannelSetupCaches<TextureCacheChannelInfo> {
55 /// Address shift for caching images into a hash table 86 /// Address shift for caching images into a hash table
56 static constexpr u64 YUZU_PAGEBITS = 20; 87 static constexpr u64 YUZU_PAGEBITS = 20;
57 88
@@ -85,13 +116,6 @@ class TextureCache {
85 PixelFormat src_format; 116 PixelFormat src_format;
86 }; 117 };
87 118
88 template <typename T>
89 struct IdentityHash {
90 [[nodiscard]] size_t operator()(T value) const noexcept {
91 return static_cast<size_t>(value);
92 }
93 };
94
95public: 119public:
96 explicit TextureCache(Runtime&, VideoCore::RasterizerInterface&); 120 explicit TextureCache(Runtime&, VideoCore::RasterizerInterface&);
97 121
@@ -179,13 +203,7 @@ public:
179 [[nodiscard]] bool IsRescaling(const ImageViewBase& image_view) const noexcept; 203 [[nodiscard]] bool IsRescaling(const ImageViewBase& image_view) const noexcept;
180 204
181 /// Create channel state. 205 /// Create channel state.
182 void CreateChannel(struct Tegra::Control::ChannelState& channel); 206 void CreateChannel(Tegra::Control::ChannelState& channel) final override;
183
184 /// Bind a channel for execution.
185 void BindToChannel(s32 id);
186
187 /// Erase channel's state.
188 void EraseChannel(s32 id);
189 207
190 std::mutex mutex; 208 std::mutex mutex;
191 209
@@ -221,6 +239,8 @@ private:
221 } 239 }
222 } 240 }
223 241
242 void OnGPUASRegister(size_t map_id) final override;
243
224 /// Runs the Garbage Collector. 244 /// Runs the Garbage Collector.
225 void RunGarbageCollector(); 245 void RunGarbageCollector();
226 246
@@ -355,51 +375,15 @@ private:
355 375
356 Runtime& runtime; 376 Runtime& runtime;
357 377
358 struct ChannelInfo {
359 ChannelInfo() = delete;
360 ChannelInfo(struct Tegra::Control::ChannelState& state) noexcept;
361 ChannelInfo(const ChannelInfo& state) = delete;
362 ChannelInfo& operator=(const ChannelInfo&) = delete;
363 ChannelInfo(ChannelInfo&& other) noexcept = default;
364 ChannelInfo& operator=(ChannelInfo&& other) noexcept = default;
365
366 Tegra::Engines::Maxwell3D& maxwell3d;
367 Tegra::Engines::KeplerCompute& kepler_compute;
368 Tegra::MemoryManager& gpu_memory;
369
370 DescriptorTable<TICEntry> graphics_image_table{gpu_memory};
371 DescriptorTable<TSCEntry> graphics_sampler_table{gpu_memory};
372 std::vector<SamplerId> graphics_sampler_ids;
373 std::vector<ImageViewId> graphics_image_view_ids;
374
375 DescriptorTable<TICEntry> compute_image_table{gpu_memory};
376 DescriptorTable<TSCEntry> compute_sampler_table{gpu_memory};
377 std::vector<SamplerId> compute_sampler_ids;
378 std::vector<ImageViewId> compute_image_view_ids;
379
380 std::unordered_map<TICEntry, ImageViewId> image_views;
381 std::unordered_map<TSCEntry, SamplerId> samplers;
382
383 std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> gpu_page_table;
384 };
385
386 std::deque<ChannelInfo> channel_storage;
387 std::deque<size_t> free_channel_ids;
388 std::unordered_map<s32, size_t> channel_map;
389
390 ChannelInfo* state;
391 size_t current_channel_id{UNSET_CHANNEL};
392 VideoCore::RasterizerInterface& rasterizer; 378 VideoCore::RasterizerInterface& rasterizer;
393 Tegra::Engines::Maxwell3D* maxwell3d; 379 std::deque<TextureCacheGPUMap> gpu_page_table_storage;
394 Tegra::Engines::KeplerCompute* kepler_compute;
395 Tegra::MemoryManager* gpu_memory;
396 380
397 RenderTargets render_targets; 381 RenderTargets render_targets;
398 382
399 std::unordered_map<RenderTargets, FramebufferId> framebuffers; 383 std::unordered_map<RenderTargets, FramebufferId> framebuffers;
400 384
401 std::unordered_map<u64, std::vector<ImageMapId>, IdentityHash<u64>> page_table; 385 std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table;
402 std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> sparse_page_table; 386 std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>> sparse_page_table;
403 std::unordered_map<ImageId, std::vector<ImageViewId>> sparse_views; 387 std::unordered_map<ImageId, std::vector<ImageViewId>> sparse_views;
404 388
405 VAddr virtual_invalid_space{}; 389 VAddr virtual_invalid_space{};