summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp1
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h51
-rw-r--r--src/video_core/fence_manager.h27
-rw-r--r--src/video_core/gpu.cpp4
-rw-r--r--src/video_core/gpu.h3
-rw-r--r--src/video_core/query_cache.h31
-rw-r--r--src/video_core/rasterizer_interface.h7
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h3
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.h6
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.cpp9
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp261
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h26
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp63
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h23
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.h16
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h28
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h6
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp19
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h21
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp23
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.h16
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp20
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.h9
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp17
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h7
-rw-r--r--src/video_core/renderer_vulkan/vk_fence_manager.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_fence_manager.h8
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp92
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h28
-rw-r--r--src/video_core/renderer_vulkan/vk_query_cache.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_query_cache.h3
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp128
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h13
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp14
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h12
-rw-r--r--src/video_core/renderer_vulkan/vk_stream_buffer.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp34
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h16
-rw-r--r--src/video_core/shader/memory_util.cpp7
-rw-r--r--src/video_core/shader/memory_util.h6
-rw-r--r--src/video_core/texture_cache/surface_params.cpp11
-rw-r--r--src/video_core/texture_cache/surface_params.h5
-rw-r--r--src/video_core/texture_cache/texture_cache.h51
-rw-r--r--src/video_core/video_core.cpp11
-rw-r--r--src/yuzu/bootmanager.cpp4
-rw-r--r--src/yuzu_cmd/yuzu.cpp5
-rw-r--r--src/yuzu_tester/yuzu.cpp1
53 files changed, 573 insertions, 633 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index c2c0eec0b..df81e8e2c 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -188,7 +188,6 @@ struct System::Impl {
188 if (!gpu_core) { 188 if (!gpu_core) {
189 return ResultStatus::ErrorVideoCore; 189 return ResultStatus::ErrorVideoCore;
190 } 190 }
191 gpu_core->Renderer().Rasterizer().SetupDirtyFlags();
192 191
193 is_powered_on = true; 192 is_powered_on = true;
194 exit_lock = false; 193 exit_lock = false;
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index b5dc68902..e7edd733f 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -51,46 +51,43 @@ public:
51 bool is_written = false, bool use_fast_cbuf = false) { 51 bool is_written = false, bool use_fast_cbuf = false) {
52 std::lock_guard lock{mutex}; 52 std::lock_guard lock{mutex};
53 53
54 auto& memory_manager = system.GPU().MemoryManager(); 54 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
55 const std::optional<VAddr> cpu_addr_opt = memory_manager.GpuToCpuAddress(gpu_addr); 55 if (!cpu_addr) {
56 if (!cpu_addr_opt) {
57 return GetEmptyBuffer(size); 56 return GetEmptyBuffer(size);
58 } 57 }
59 const VAddr cpu_addr = *cpu_addr_opt;
60 58
61 // Cache management is a big overhead, so only cache entries with a given size. 59 // Cache management is a big overhead, so only cache entries with a given size.
62 // TODO: Figure out which size is the best for given games. 60 // TODO: Figure out which size is the best for given games.
63 constexpr std::size_t max_stream_size = 0x800; 61 constexpr std::size_t max_stream_size = 0x800;
64 if (use_fast_cbuf || size < max_stream_size) { 62 if (use_fast_cbuf || size < max_stream_size) {
65 if (!is_written && !IsRegionWritten(cpu_addr, cpu_addr + size - 1)) { 63 if (!is_written && !IsRegionWritten(*cpu_addr, *cpu_addr + size - 1)) {
66 const bool is_granular = memory_manager.IsGranularRange(gpu_addr, size); 64 const bool is_granular = gpu_memory.IsGranularRange(gpu_addr, size);
67 if (use_fast_cbuf) { 65 if (use_fast_cbuf) {
68 u8* dest; 66 u8* dest;
69 if (is_granular) { 67 if (is_granular) {
70 dest = memory_manager.GetPointer(gpu_addr); 68 dest = gpu_memory.GetPointer(gpu_addr);
71 } else { 69 } else {
72 staging_buffer.resize(size); 70 staging_buffer.resize(size);
73 dest = staging_buffer.data(); 71 dest = staging_buffer.data();
74 memory_manager.ReadBlockUnsafe(gpu_addr, dest, size); 72 gpu_memory.ReadBlockUnsafe(gpu_addr, dest, size);
75 } 73 }
76 return ConstBufferUpload(dest, size); 74 return ConstBufferUpload(dest, size);
77 } 75 }
78 if (is_granular) { 76 if (is_granular) {
79 u8* const host_ptr = memory_manager.GetPointer(gpu_addr); 77 u8* const host_ptr = gpu_memory.GetPointer(gpu_addr);
80 return StreamBufferUpload(size, alignment, [host_ptr, size](u8* dest) { 78 return StreamBufferUpload(size, alignment, [host_ptr, size](u8* dest) {
81 std::memcpy(dest, host_ptr, size); 79 std::memcpy(dest, host_ptr, size);
82 }); 80 });
83 } else { 81 } else {
84 return StreamBufferUpload( 82 return StreamBufferUpload(size, alignment, [this, gpu_addr, size](u8* dest) {
85 size, alignment, [&memory_manager, gpu_addr, size](u8* dest) { 83 gpu_memory.ReadBlockUnsafe(gpu_addr, dest, size);
86 memory_manager.ReadBlockUnsafe(gpu_addr, dest, size); 84 });
87 });
88 } 85 }
89 } 86 }
90 } 87 }
91 88
92 Buffer* const block = GetBlock(cpu_addr, size); 89 Buffer* const block = GetBlock(*cpu_addr, size);
93 MapInterval* const map = MapAddress(block, gpu_addr, cpu_addr, size); 90 MapInterval* const map = MapAddress(block, gpu_addr, *cpu_addr, size);
94 if (!map) { 91 if (!map) {
95 return GetEmptyBuffer(size); 92 return GetEmptyBuffer(size);
96 } 93 }
@@ -106,7 +103,7 @@ public:
106 } 103 }
107 } 104 }
108 105
109 return BufferInfo{block->Handle(), block->Offset(cpu_addr), block->Address()}; 106 return BufferInfo{block->Handle(), block->Offset(*cpu_addr), block->Address()};
110 } 107 }
111 108
112 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset. 109 /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset.
@@ -262,9 +259,11 @@ public:
262 virtual BufferInfo GetEmptyBuffer(std::size_t size) = 0; 259 virtual BufferInfo GetEmptyBuffer(std::size_t size) = 0;
263 260
264protected: 261protected:
265 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, 262 explicit BufferCache(VideoCore::RasterizerInterface& rasterizer_,
266 std::unique_ptr<StreamBuffer> stream_buffer) 263 Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_,
267 : rasterizer{rasterizer}, system{system}, stream_buffer{std::move(stream_buffer)} {} 264 std::unique_ptr<StreamBuffer> stream_buffer_)
265 : rasterizer{rasterizer_}, gpu_memory{gpu_memory_}, cpu_memory{cpu_memory_},
266 stream_buffer{std::move(stream_buffer_)}, stream_buffer_handle{stream_buffer->Handle()} {}
268 267
269 ~BufferCache() = default; 268 ~BufferCache() = default;
270 269
@@ -326,14 +325,13 @@ private:
326 MapInterval* MapAddress(Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size) { 325 MapInterval* MapAddress(Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size) {
327 const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size); 326 const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size);
328 if (overlaps.empty()) { 327 if (overlaps.empty()) {
329 auto& memory_manager = system.GPU().MemoryManager();
330 const VAddr cpu_addr_end = cpu_addr + size; 328 const VAddr cpu_addr_end = cpu_addr + size;
331 if (memory_manager.IsGranularRange(gpu_addr, size)) { 329 if (gpu_memory.IsGranularRange(gpu_addr, size)) {
332 u8* host_ptr = memory_manager.GetPointer(gpu_addr); 330 u8* const host_ptr = gpu_memory.GetPointer(gpu_addr);
333 block->Upload(block->Offset(cpu_addr), size, host_ptr); 331 block->Upload(block->Offset(cpu_addr), size, host_ptr);
334 } else { 332 } else {
335 staging_buffer.resize(size); 333 staging_buffer.resize(size);
336 memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size); 334 gpu_memory.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size);
337 block->Upload(block->Offset(cpu_addr), size, staging_buffer.data()); 335 block->Upload(block->Offset(cpu_addr), size, staging_buffer.data());
338 } 336 }
339 return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr)); 337 return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr));
@@ -392,7 +390,7 @@ private:
392 continue; 390 continue;
393 } 391 }
394 staging_buffer.resize(size); 392 staging_buffer.resize(size);
395 system.Memory().ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size); 393 cpu_memory.ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size);
396 block->Upload(block->Offset(interval.lower()), size, staging_buffer.data()); 394 block->Upload(block->Offset(interval.lower()), size, staging_buffer.data());
397 } 395 }
398 } 396 }
@@ -431,7 +429,7 @@ private:
431 const std::size_t size = map->end - map->start; 429 const std::size_t size = map->end - map->start;
432 staging_buffer.resize(size); 430 staging_buffer.resize(size);
433 block->Download(block->Offset(map->start), size, staging_buffer.data()); 431 block->Download(block->Offset(map->start), size, staging_buffer.data());
434 system.Memory().WriteBlockUnsafe(map->start, staging_buffer.data(), size); 432 cpu_memory.WriteBlockUnsafe(map->start, staging_buffer.data(), size);
435 map->MarkAsModified(false, 0); 433 map->MarkAsModified(false, 0);
436 } 434 }
437 435
@@ -567,7 +565,8 @@ private:
567 } 565 }
568 566
569 VideoCore::RasterizerInterface& rasterizer; 567 VideoCore::RasterizerInterface& rasterizer;
570 Core::System& system; 568 Tegra::MemoryManager& gpu_memory;
569 Core::Memory::Memory& cpu_memory;
571 570
572 std::unique_ptr<StreamBuffer> stream_buffer; 571 std::unique_ptr<StreamBuffer> stream_buffer;
573 BufferType stream_buffer_handle; 572 BufferType stream_buffer_handle;
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index 06cc12d5a..de6991ef6 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -74,8 +74,6 @@ public:
74 } 74 }
75 75
76 void WaitPendingFences() { 76 void WaitPendingFences() {
77 auto& gpu{system.GPU()};
78 auto& memory_manager{gpu.MemoryManager()};
79 while (!fences.empty()) { 77 while (!fences.empty()) {
80 TFence& current_fence = fences.front(); 78 TFence& current_fence = fences.front();
81 if (ShouldWait()) { 79 if (ShouldWait()) {
@@ -83,8 +81,8 @@ public:
83 } 81 }
84 PopAsyncFlushes(); 82 PopAsyncFlushes();
85 if (current_fence->IsSemaphore()) { 83 if (current_fence->IsSemaphore()) {
86 memory_manager.template Write<u32>(current_fence->GetAddress(), 84 gpu_memory.template Write<u32>(current_fence->GetAddress(),
87 current_fence->GetPayload()); 85 current_fence->GetPayload());
88 } else { 86 } else {
89 gpu.IncrementSyncPoint(current_fence->GetPayload()); 87 gpu.IncrementSyncPoint(current_fence->GetPayload());
90 } 88 }
@@ -93,13 +91,13 @@ public:
93 } 91 }
94 92
95protected: 93protected:
96 FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 94 explicit FenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::GPU& gpu_,
97 TTextureCache& texture_cache, TTBufferCache& buffer_cache, 95 TTextureCache& texture_cache_, TTBufferCache& buffer_cache_,
98 TQueryCache& query_cache) 96 TQueryCache& query_cache_)
99 : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, 97 : rasterizer{rasterizer_}, gpu{gpu_}, gpu_memory{gpu.MemoryManager()},
100 buffer_cache{buffer_cache}, query_cache{query_cache} {} 98 texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, query_cache{query_cache_} {}
101 99
102 virtual ~FenceManager() {} 100 virtual ~FenceManager() = default;
103 101
104 /// Creates a Sync Point Fence Interface, does not create a backend fence if 'is_stubbed' is 102 /// Creates a Sync Point Fence Interface, does not create a backend fence if 'is_stubbed' is
105 /// true 103 /// true
@@ -113,16 +111,15 @@ protected:
113 /// Waits until a fence has been signalled by the host GPU. 111 /// Waits until a fence has been signalled by the host GPU.
114 virtual void WaitFence(TFence& fence) = 0; 112 virtual void WaitFence(TFence& fence) = 0;
115 113
116 Core::System& system;
117 VideoCore::RasterizerInterface& rasterizer; 114 VideoCore::RasterizerInterface& rasterizer;
115 Tegra::GPU& gpu;
116 Tegra::MemoryManager& gpu_memory;
118 TTextureCache& texture_cache; 117 TTextureCache& texture_cache;
119 TTBufferCache& buffer_cache; 118 TTBufferCache& buffer_cache;
120 TQueryCache& query_cache; 119 TQueryCache& query_cache;
121 120
122private: 121private:
123 void TryReleasePendingFences() { 122 void TryReleasePendingFences() {
124 auto& gpu{system.GPU()};
125 auto& memory_manager{gpu.MemoryManager()};
126 while (!fences.empty()) { 123 while (!fences.empty()) {
127 TFence& current_fence = fences.front(); 124 TFence& current_fence = fences.front();
128 if (ShouldWait() && !IsFenceSignaled(current_fence)) { 125 if (ShouldWait() && !IsFenceSignaled(current_fence)) {
@@ -130,8 +127,8 @@ private:
130 } 127 }
131 PopAsyncFlushes(); 128 PopAsyncFlushes();
132 if (current_fence->IsSemaphore()) { 129 if (current_fence->IsSemaphore()) {
133 memory_manager.template Write<u32>(current_fence->GetAddress(), 130 gpu_memory.template Write<u32>(current_fence->GetAddress(),
134 current_fence->GetPayload()); 131 current_fence->GetPayload());
135 } else { 132 } else {
136 gpu.IncrementSyncPoint(current_fence->GetPayload()); 133 gpu.IncrementSyncPoint(current_fence->GetPayload());
137 } 134 }
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index acb6e6d46..4bb9256e9 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -28,8 +28,8 @@ namespace Tegra {
28MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); 28MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192));
29 29
30GPU::GPU(Core::System& system_, bool is_async_) 30GPU::GPU(Core::System& system_, bool is_async_)
31 : system{system_}, dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)}, 31 : system{system_}, memory_manager{std::make_unique<Tegra::MemoryManager>(system)},
32 memory_manager{std::make_unique<Tegra::MemoryManager>(system)}, 32 dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)},
33 maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)}, 33 maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)},
34 fermi_2d{std::make_unique<Engines::Fermi2D>()}, 34 fermi_2d{std::make_unique<Engines::Fermi2D>()},
35 kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, 35 kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)},
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index c7d11deb2..2d15d1c6f 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -347,12 +347,11 @@ private:
347 347
348protected: 348protected:
349 Core::System& system; 349 Core::System& system;
350 std::unique_ptr<Tegra::MemoryManager> memory_manager;
350 std::unique_ptr<Tegra::DmaPusher> dma_pusher; 351 std::unique_ptr<Tegra::DmaPusher> dma_pusher;
351 std::unique_ptr<VideoCore::RendererBase> renderer; 352 std::unique_ptr<VideoCore::RendererBase> renderer;
352 353
353private: 354private:
354 std::unique_ptr<Tegra::MemoryManager> memory_manager;
355
356 /// Mapping of command subchannels to their bound engine ids 355 /// Mapping of command subchannels to their bound engine ids
357 std::array<EngineID, 8> bound_engines = {}; 356 std::array<EngineID, 8> bound_engines = {};
358 /// 3D engine 357 /// 3D engine
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h
index 0d3a88765..d13a66bb6 100644
--- a/src/video_core/query_cache.h
+++ b/src/video_core/query_cache.h
@@ -95,10 +95,12 @@ template <class QueryCache, class CachedQuery, class CounterStream, class HostCo
95 class QueryPool> 95 class QueryPool>
96class QueryCacheBase { 96class QueryCacheBase {
97public: 97public:
98 explicit QueryCacheBase(Core::System& system, VideoCore::RasterizerInterface& rasterizer) 98 explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_,
99 : system{system}, rasterizer{rasterizer}, streams{{CounterStream{ 99 Tegra::Engines::Maxwell3D& maxwell3d_,
100 static_cast<QueryCache&>(*this), 100 Tegra::MemoryManager& gpu_memory_)
101 VideoCore::QueryType::SamplesPassed}}} {} 101 : rasterizer{rasterizer_}, maxwell3d{maxwell3d_},
102 gpu_memory{gpu_memory_}, streams{{CounterStream{static_cast<QueryCache&>(*this),
103 VideoCore::QueryType::SamplesPassed}}} {}
102 104
103 void InvalidateRegion(VAddr addr, std::size_t size) { 105 void InvalidateRegion(VAddr addr, std::size_t size) {
104 std::unique_lock lock{mutex}; 106 std::unique_lock lock{mutex};
@@ -118,29 +120,27 @@ public:
118 */ 120 */
119 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) { 121 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) {
120 std::unique_lock lock{mutex}; 122 std::unique_lock lock{mutex};
121 auto& memory_manager = system.GPU().MemoryManager(); 123 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
122 const std::optional<VAddr> cpu_addr_opt = memory_manager.GpuToCpuAddress(gpu_addr); 124 ASSERT(cpu_addr);
123 ASSERT(cpu_addr_opt);
124 VAddr cpu_addr = *cpu_addr_opt;
125 125
126 CachedQuery* query = TryGet(cpu_addr); 126 CachedQuery* query = TryGet(*cpu_addr);
127 if (!query) { 127 if (!query) {
128 ASSERT_OR_EXECUTE(cpu_addr_opt, return;); 128 ASSERT_OR_EXECUTE(cpu_addr, return;);
129 const auto host_ptr = memory_manager.GetPointer(gpu_addr); 129 u8* const host_ptr = gpu_memory.GetPointer(gpu_addr);
130 130
131 query = Register(type, cpu_addr, host_ptr, timestamp.has_value()); 131 query = Register(type, *cpu_addr, host_ptr, timestamp.has_value());
132 } 132 }
133 133
134 query->BindCounter(Stream(type).Current(), timestamp); 134 query->BindCounter(Stream(type).Current(), timestamp);
135 if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { 135 if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) {
136 AsyncFlushQuery(cpu_addr); 136 AsyncFlushQuery(*cpu_addr);
137 } 137 }
138 } 138 }
139 139
140 /// Updates counters from GPU state. Expected to be called once per draw, clear or dispatch. 140 /// Updates counters from GPU state. Expected to be called once per draw, clear or dispatch.
141 void UpdateCounters() { 141 void UpdateCounters() {
142 std::unique_lock lock{mutex}; 142 std::unique_lock lock{mutex};
143 const auto& regs = system.GPU().Maxwell3D().regs; 143 const auto& regs = maxwell3d.regs;
144 Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable); 144 Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable);
145 } 145 }
146 146
@@ -270,8 +270,9 @@ private:
270 static constexpr std::uintptr_t PAGE_SIZE = 4096; 270 static constexpr std::uintptr_t PAGE_SIZE = 4096;
271 static constexpr unsigned PAGE_BITS = 12; 271 static constexpr unsigned PAGE_BITS = 12;
272 272
273 Core::System& system;
274 VideoCore::RasterizerInterface& rasterizer; 273 VideoCore::RasterizerInterface& rasterizer;
274 Tegra::Engines::Maxwell3D& maxwell3d;
275 Tegra::MemoryManager& gpu_memory;
275 276
276 std::recursive_mutex mutex; 277 std::recursive_mutex mutex;
277 278
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 3cbdac8e7..b3e0919f8 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -106,11 +106,8 @@ public:
106 virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {} 106 virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {}
107 107
108 /// Initialize disk cached resources for the game being emulated 108 /// Initialize disk cached resources for the game being emulated
109 virtual void LoadDiskResources(const std::atomic_bool& stop_loading = false, 109 virtual void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
110 const DiskResourceLoadCallback& callback = {}) {} 110 const DiskResourceLoadCallback& callback) {}
111
112 /// Initializes renderer dirty flags
113 virtual void SetupDirtyFlags() {}
114 111
115 /// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver. 112 /// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver.
116 GuestDriverProfile& AccessGuestDriverProfile() { 113 GuestDriverProfile& AccessGuestDriverProfile() {
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index e866d8f2f..b1c4cd62f 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -59,9 +59,10 @@ void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst
59 static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size)); 59 static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
60} 60}
61 61
62OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, 62OGLBufferCache::OGLBufferCache(VideoCore::RasterizerInterface& rasterizer,
63 Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
63 const Device& device_, std::size_t stream_size) 64 const Device& device_, std::size_t stream_size)
64 : GenericBufferCache{rasterizer, system, 65 : GenericBufferCache{rasterizer, gpu_memory, cpu_memory,
65 std::make_unique<OGLStreamBuffer>(device_, stream_size, true)}, 66 std::make_unique<OGLStreamBuffer>(device_, stream_size, true)},
66 device{device_} { 67 device{device_} {
67 if (!device.HasFastBufferSubData()) { 68 if (!device.HasFastBufferSubData()) {
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index 88fdc0536..f75b32e31 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -52,7 +52,8 @@ private:
52using GenericBufferCache = VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer>; 52using GenericBufferCache = VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer>;
53class OGLBufferCache final : public GenericBufferCache { 53class OGLBufferCache final : public GenericBufferCache {
54public: 54public:
55 explicit OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, 55 explicit OGLBufferCache(VideoCore::RasterizerInterface& rasterizer,
56 Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
56 const Device& device, std::size_t stream_size); 57 const Device& device, std::size_t stream_size);
57 ~OGLBufferCache(); 58 ~OGLBufferCache();
58 59
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp
index 3d2588dd2..b532fdcc2 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp
@@ -45,11 +45,10 @@ void GLInnerFence::Wait() {
45 glClientWaitSync(sync_object.handle, 0, GL_TIMEOUT_IGNORED); 45 glClientWaitSync(sync_object.handle, 0, GL_TIMEOUT_IGNORED);
46} 46}
47 47
48FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, 48FenceManagerOpenGL::FenceManagerOpenGL(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
49 VideoCore::RasterizerInterface& rasterizer,
50 TextureCacheOpenGL& texture_cache, 49 TextureCacheOpenGL& texture_cache,
51 OGLBufferCache& buffer_cache, QueryCache& query_cache) 50 OGLBufferCache& buffer_cache, QueryCache& query_cache)
52 : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache, query_cache) {} 51 : GenericFenceManager{rasterizer, gpu, texture_cache, buffer_cache, query_cache} {}
53 52
54Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) { 53Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) {
55 return std::make_shared<GLInnerFence>(value, is_stubbed); 54 return std::make_shared<GLInnerFence>(value, is_stubbed);
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h
index 1686cf5c8..da1dcdace 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.h
+++ b/src/video_core/renderer_opengl/gl_fence_manager.h
@@ -37,9 +37,9 @@ using GenericFenceManager =
37 37
38class FenceManagerOpenGL final : public GenericFenceManager { 38class FenceManagerOpenGL final : public GenericFenceManager {
39public: 39public:
40 FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 40 explicit FenceManagerOpenGL(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
41 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache, 41 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache,
42 QueryCache& query_cache); 42 QueryCache& query_cache);
43 43
44protected: 44protected:
45 Fence CreateFence(u32 value, bool is_stubbed) override; 45 Fence CreateFence(u32 value, bool is_stubbed) override;
diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp
index d7ba57aca..2bb8ec2b8 100644
--- a/src/video_core/renderer_opengl/gl_query_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_query_cache.cpp
@@ -30,12 +30,13 @@ constexpr GLenum GetTarget(VideoCore::QueryType type) {
30 30
31} // Anonymous namespace 31} // Anonymous namespace
32 32
33QueryCache::QueryCache(Core::System& system, RasterizerOpenGL& gl_rasterizer) 33QueryCache::QueryCache(RasterizerOpenGL& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d,
34 Tegra::MemoryManager& gpu_memory)
34 : VideoCommon::QueryCacheBase< 35 : VideoCommon::QueryCacheBase<
35 QueryCache, CachedQuery, CounterStream, HostCounter, 36 QueryCache, CachedQuery, CounterStream, HostCounter,
36 std::vector<OGLQuery>>{system, 37 std::vector<OGLQuery>>{static_cast<VideoCore::RasterizerInterface&>(rasterizer),
37 static_cast<VideoCore::RasterizerInterface&>(gl_rasterizer)}, 38 maxwell3d, gpu_memory},
38 gl_rasterizer{gl_rasterizer} {} 39 gl_rasterizer{rasterizer} {}
39 40
40QueryCache::~QueryCache() = default; 41QueryCache::~QueryCache() = default;
41 42
diff --git a/src/video_core/renderer_opengl/gl_query_cache.h b/src/video_core/renderer_opengl/gl_query_cache.h
index d8e7052a1..dd626b66b 100644
--- a/src/video_core/renderer_opengl/gl_query_cache.h
+++ b/src/video_core/renderer_opengl/gl_query_cache.h
@@ -29,7 +29,8 @@ using CounterStream = VideoCommon::CounterStreamBase<QueryCache, HostCounter>;
29class QueryCache final : public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream, 29class QueryCache final : public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream,
30 HostCounter, std::vector<OGLQuery>> { 30 HostCounter, std::vector<OGLQuery>> {
31public: 31public:
32 explicit QueryCache(Core::System& system, RasterizerOpenGL& rasterizer); 32 explicit QueryCache(RasterizerOpenGL& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d,
33 Tegra::MemoryManager& gpu_memory);
33 ~QueryCache(); 34 ~QueryCache();
34 35
35 OGLQuery AllocateQuery(VideoCore::QueryType type); 36 OGLQuery AllocateQuery(VideoCore::QueryType type);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4af5824cd..bbb2eb17c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -153,16 +153,19 @@ void UpdateBindlessPointers(GLenum target, GLuint64EXT* pointers, std::size_t nu
153 153
154} // Anonymous namespace 154} // Anonymous namespace
155 155
156RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 156RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu_,
157 const Device& device, ScreenInfo& info, 157 Core::Memory::Memory& cpu_memory, const Device& device_,
158 ProgramManager& program_manager, StateTracker& state_tracker) 158 ScreenInfo& screen_info_, ProgramManager& program_manager_,
159 : RasterizerAccelerated{system.Memory()}, device{device}, texture_cache{system, *this, device, 159 StateTracker& state_tracker_)
160 state_tracker}, 160 : RasterizerAccelerated{cpu_memory}, gpu(gpu_), maxwell3d(gpu.Maxwell3D()),
161 shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, 161 kepler_compute(gpu.KeplerCompute()), gpu_memory(gpu.MemoryManager()), device(device_),
162 buffer_cache{*this, system, device, STREAM_BUFFER_SIZE}, 162 screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_),
163 fence_manager{system, *this, texture_cache, buffer_cache, query_cache}, system{system}, 163 texture_cache(*this, maxwell3d, gpu_memory, device, state_tracker),
164 screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker}, 164 shader_cache(*this, emu_window, gpu, maxwell3d, kepler_compute, gpu_memory, device),
165 async_shaders{emu_window} { 165 query_cache(*this, maxwell3d, gpu_memory),
166 buffer_cache(*this, gpu_memory, cpu_memory, device, STREAM_BUFFER_SIZE),
167 fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache),
168 async_shaders(emu_window) {
166 CheckExtensions(); 169 CheckExtensions();
167 170
168 unified_uniform_buffer.Create(); 171 unified_uniform_buffer.Create();
@@ -196,8 +199,7 @@ void RasterizerOpenGL::CheckExtensions() {
196} 199}
197 200
198void RasterizerOpenGL::SetupVertexFormat() { 201void RasterizerOpenGL::SetupVertexFormat() {
199 auto& gpu = system.GPU().Maxwell3D(); 202 auto& flags = maxwell3d.dirty.flags;
200 auto& flags = gpu.dirty.flags;
201 if (!flags[Dirty::VertexFormats]) { 203 if (!flags[Dirty::VertexFormats]) {
202 return; 204 return;
203 } 205 }
@@ -217,7 +219,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
217 } 219 }
218 flags[Dirty::VertexFormat0 + index] = false; 220 flags[Dirty::VertexFormat0 + index] = false;
219 221
220 const auto attrib = gpu.regs.vertex_attrib_format[index]; 222 const auto attrib = maxwell3d.regs.vertex_attrib_format[index];
221 const auto gl_index = static_cast<GLuint>(index); 223 const auto gl_index = static_cast<GLuint>(index);
222 224
223 // Disable constant attributes. 225 // Disable constant attributes.
@@ -241,8 +243,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
241} 243}
242 244
243void RasterizerOpenGL::SetupVertexBuffer() { 245void RasterizerOpenGL::SetupVertexBuffer() {
244 auto& gpu = system.GPU().Maxwell3D(); 246 auto& flags = maxwell3d.dirty.flags;
245 auto& flags = gpu.dirty.flags;
246 if (!flags[Dirty::VertexBuffers]) { 247 if (!flags[Dirty::VertexBuffers]) {
247 return; 248 return;
248 } 249 }
@@ -253,7 +254,7 @@ void RasterizerOpenGL::SetupVertexBuffer() {
253 const bool use_unified_memory = device.HasVertexBufferUnifiedMemory(); 254 const bool use_unified_memory = device.HasVertexBufferUnifiedMemory();
254 255
255 // Upload all guest vertex arrays sequentially to our buffer 256 // Upload all guest vertex arrays sequentially to our buffer
256 const auto& regs = gpu.regs; 257 const auto& regs = maxwell3d.regs;
257 for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_BINDINGS; ++index) { 258 for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_BINDINGS; ++index) {
258 if (!flags[Dirty::VertexBuffer0 + index]) { 259 if (!flags[Dirty::VertexBuffer0 + index]) {
259 continue; 260 continue;
@@ -290,14 +291,13 @@ void RasterizerOpenGL::SetupVertexBuffer() {
290} 291}
291 292
292void RasterizerOpenGL::SetupVertexInstances() { 293void RasterizerOpenGL::SetupVertexInstances() {
293 auto& gpu = system.GPU().Maxwell3D(); 294 auto& flags = maxwell3d.dirty.flags;
294 auto& flags = gpu.dirty.flags;
295 if (!flags[Dirty::VertexInstances]) { 295 if (!flags[Dirty::VertexInstances]) {
296 return; 296 return;
297 } 297 }
298 flags[Dirty::VertexInstances] = false; 298 flags[Dirty::VertexInstances] = false;
299 299
300 const auto& regs = gpu.regs; 300 const auto& regs = maxwell3d.regs;
301 for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) { 301 for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) {
302 if (!flags[Dirty::VertexInstance0 + index]) { 302 if (!flags[Dirty::VertexInstance0 + index]) {
303 continue; 303 continue;
@@ -313,7 +313,7 @@ void RasterizerOpenGL::SetupVertexInstances() {
313 313
314GLintptr RasterizerOpenGL::SetupIndexBuffer() { 314GLintptr RasterizerOpenGL::SetupIndexBuffer() {
315 MICROPROFILE_SCOPE(OpenGL_Index); 315 MICROPROFILE_SCOPE(OpenGL_Index);
316 const auto& regs = system.GPU().Maxwell3D().regs; 316 const auto& regs = maxwell3d.regs;
317 const std::size_t size = CalculateIndexBufferSize(); 317 const std::size_t size = CalculateIndexBufferSize();
318 const auto info = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); 318 const auto info = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
319 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, info.handle); 319 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, info.handle);
@@ -322,15 +322,14 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() {
322 322
323void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { 323void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
324 MICROPROFILE_SCOPE(OpenGL_Shader); 324 MICROPROFILE_SCOPE(OpenGL_Shader);
325 auto& gpu = system.GPU().Maxwell3D();
326 u32 clip_distances = 0; 325 u32 clip_distances = 0;
327 326
328 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 327 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
329 const auto& shader_config = gpu.regs.shader_config[index]; 328 const auto& shader_config = maxwell3d.regs.shader_config[index];
330 const auto program{static_cast<Maxwell::ShaderProgram>(index)}; 329 const auto program{static_cast<Maxwell::ShaderProgram>(index)};
331 330
332 // Skip stages that are not enabled 331 // Skip stages that are not enabled
333 if (!gpu.regs.IsShaderConfigEnabled(index)) { 332 if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
334 switch (program) { 333 switch (program) {
335 case Maxwell::ShaderProgram::Geometry: 334 case Maxwell::ShaderProgram::Geometry:
336 program_manager.UseGeometryShader(0); 335 program_manager.UseGeometryShader(0);
@@ -391,11 +390,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
391 } 390 }
392 391
393 SyncClipEnabled(clip_distances); 392 SyncClipEnabled(clip_distances);
394 gpu.dirty.flags[Dirty::Shaders] = false; 393 maxwell3d.dirty.flags[Dirty::Shaders] = false;
395} 394}
396 395
397std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { 396std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
398 const auto& regs = system.GPU().Maxwell3D().regs; 397 const auto& regs = maxwell3d.regs;
399 398
400 std::size_t size = 0; 399 std::size_t size = 0;
401 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { 400 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
@@ -413,34 +412,27 @@ std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
413} 412}
414 413
415std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const { 414std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const {
416 const auto& regs = system.GPU().Maxwell3D().regs; 415 return static_cast<std::size_t>(maxwell3d.regs.index_array.count) *
417 416 static_cast<std::size_t>(maxwell3d.regs.index_array.FormatSizeInBytes());
418 return static_cast<std::size_t>(regs.index_array.count) *
419 static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
420} 417}
421 418
422void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, 419void RasterizerOpenGL::LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
423 const VideoCore::DiskResourceLoadCallback& callback) { 420 const VideoCore::DiskResourceLoadCallback& callback) {
424 shader_cache.LoadDiskCache(stop_loading, callback); 421 shader_cache.LoadDiskCache(title_id, stop_loading, callback);
425}
426
427void RasterizerOpenGL::SetupDirtyFlags() {
428 state_tracker.Initialize();
429} 422}
430 423
431void RasterizerOpenGL::ConfigureFramebuffers() { 424void RasterizerOpenGL::ConfigureFramebuffers() {
432 MICROPROFILE_SCOPE(OpenGL_Framebuffer); 425 MICROPROFILE_SCOPE(OpenGL_Framebuffer);
433 auto& gpu = system.GPU().Maxwell3D(); 426 if (!maxwell3d.dirty.flags[VideoCommon::Dirty::RenderTargets]) {
434 if (!gpu.dirty.flags[VideoCommon::Dirty::RenderTargets]) {
435 return; 427 return;
436 } 428 }
437 gpu.dirty.flags[VideoCommon::Dirty::RenderTargets] = false; 429 maxwell3d.dirty.flags[VideoCommon::Dirty::RenderTargets] = false;
438 430
439 texture_cache.GuardRenderTargets(true); 431 texture_cache.GuardRenderTargets(true);
440 432
441 View depth_surface = texture_cache.GetDepthBufferSurface(true); 433 View depth_surface = texture_cache.GetDepthBufferSurface(true);
442 434
443 const auto& regs = gpu.regs; 435 const auto& regs = maxwell3d.regs;
444 UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0); 436 UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0);
445 437
446 // Bind the framebuffer surfaces 438 // Bind the framebuffer surfaces
@@ -472,8 +464,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
472} 464}
473 465
474void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil) { 466void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil) {
475 auto& gpu = system.GPU().Maxwell3D(); 467 const auto& regs = maxwell3d.regs;
476 const auto& regs = gpu.regs;
477 468
478 texture_cache.GuardRenderTargets(true); 469 texture_cache.GuardRenderTargets(true);
479 View color_surface; 470 View color_surface;
@@ -523,12 +514,11 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_de
523} 514}
524 515
525void RasterizerOpenGL::Clear() { 516void RasterizerOpenGL::Clear() {
526 const auto& gpu = system.GPU().Maxwell3D(); 517 if (!maxwell3d.ShouldExecute()) {
527 if (!gpu.ShouldExecute()) {
528 return; 518 return;
529 } 519 }
530 520
531 const auto& regs = gpu.regs; 521 const auto& regs = maxwell3d.regs;
532 bool use_color{}; 522 bool use_color{};
533 bool use_depth{}; 523 bool use_depth{};
534 bool use_stencil{}; 524 bool use_stencil{};
@@ -593,7 +583,6 @@ void RasterizerOpenGL::Clear() {
593 583
594void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { 584void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
595 MICROPROFILE_SCOPE(OpenGL_Drawing); 585 MICROPROFILE_SCOPE(OpenGL_Drawing);
596 auto& gpu = system.GPU().Maxwell3D();
597 586
598 query_cache.UpdateCounters(); 587 query_cache.UpdateCounters();
599 588
@@ -641,7 +630,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
641 630
642 if (invalidated) { 631 if (invalidated) {
643 // When the stream buffer has been invalidated, we have to consider vertex buffers as dirty 632 // When the stream buffer has been invalidated, we have to consider vertex buffers as dirty
644 auto& dirty = gpu.dirty.flags; 633 auto& dirty = maxwell3d.dirty.flags;
645 dirty[Dirty::VertexBuffers] = true; 634 dirty[Dirty::VertexBuffers] = true;
646 for (int index = Dirty::VertexBuffer0; index <= Dirty::VertexBuffer31; ++index) { 635 for (int index = Dirty::VertexBuffer0; index <= Dirty::VertexBuffer31; ++index) {
647 dirty[index] = true; 636 dirty[index] = true;
@@ -662,7 +651,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
662 // Setup emulation uniform buffer. 651 // Setup emulation uniform buffer.
663 if (!device.UseAssemblyShaders()) { 652 if (!device.UseAssemblyShaders()) {
664 MaxwellUniformData ubo; 653 MaxwellUniformData ubo;
665 ubo.SetFromRegs(gpu); 654 ubo.SetFromRegs(maxwell3d);
666 const auto info = 655 const auto info =
667 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); 656 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
668 glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, info.handle, info.offset, 657 glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, info.handle, info.offset,
@@ -671,7 +660,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
671 660
672 // Setup shaders and their used resources. 661 // Setup shaders and their used resources.
673 texture_cache.GuardSamplers(true); 662 texture_cache.GuardSamplers(true);
674 const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(gpu.regs.draw.topology); 663 const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology);
675 SetupShaders(primitive_mode); 664 SetupShaders(primitive_mode);
676 texture_cache.GuardSamplers(false); 665 texture_cache.GuardSamplers(false);
677 666
@@ -688,14 +677,14 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
688 677
689 BeginTransformFeedback(primitive_mode); 678 BeginTransformFeedback(primitive_mode);
690 679
691 const GLuint base_instance = static_cast<GLuint>(gpu.regs.vb_base_instance); 680 const GLuint base_instance = static_cast<GLuint>(maxwell3d.regs.vb_base_instance);
692 const GLsizei num_instances = 681 const GLsizei num_instances =
693 static_cast<GLsizei>(is_instanced ? gpu.mme_draw.instance_count : 1); 682 static_cast<GLsizei>(is_instanced ? maxwell3d.mme_draw.instance_count : 1);
694 if (is_indexed) { 683 if (is_indexed) {
695 const GLint base_vertex = static_cast<GLint>(gpu.regs.vb_element_base); 684 const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vb_element_base);
696 const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.index_array.count); 685 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.index_array.count);
697 const GLvoid* offset = reinterpret_cast<const GLvoid*>(index_buffer_offset); 686 const GLvoid* offset = reinterpret_cast<const GLvoid*>(index_buffer_offset);
698 const GLenum format = MaxwellToGL::IndexFormat(gpu.regs.index_array.format); 687 const GLenum format = MaxwellToGL::IndexFormat(maxwell3d.regs.index_array.format);
699 if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { 688 if (num_instances == 1 && base_instance == 0 && base_vertex == 0) {
700 glDrawElements(primitive_mode, num_vertices, format, offset); 689 glDrawElements(primitive_mode, num_vertices, format, offset);
701 } else if (num_instances == 1 && base_instance == 0) { 690 } else if (num_instances == 1 && base_instance == 0) {
@@ -714,8 +703,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
714 base_instance); 703 base_instance);
715 } 704 }
716 } else { 705 } else {
717 const GLint base_vertex = static_cast<GLint>(gpu.regs.vertex_buffer.first); 706 const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vertex_buffer.first);
718 const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.vertex_buffer.count); 707 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.vertex_buffer.count);
719 if (num_instances == 1 && base_instance == 0) { 708 if (num_instances == 1 && base_instance == 0) {
720 glDrawArrays(primitive_mode, base_vertex, num_vertices); 709 glDrawArrays(primitive_mode, base_vertex, num_vertices);
721 } else if (base_instance == 0) { 710 } else if (base_instance == 0) {
@@ -730,7 +719,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
730 719
731 ++num_queued_commands; 720 ++num_queued_commands;
732 721
733 system.GPU().TickWork(); 722 gpu.TickWork();
734} 723}
735 724
736void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { 725void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
@@ -753,7 +742,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
753 742
754 buffer_cache.Unmap(); 743 buffer_cache.Unmap();
755 744
756 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 745 const auto& launch_desc = kepler_compute.launch_description;
746 program_manager.BindCompute(kernel->GetHandle());
757 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); 747 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
758 ++num_queued_commands; 748 ++num_queued_commands;
759} 749}
@@ -815,17 +805,14 @@ void RasterizerOpenGL::SyncGuestHost() {
815} 805}
816 806
817void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { 807void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) {
818 auto& gpu{system.GPU()};
819 if (!gpu.IsAsync()) { 808 if (!gpu.IsAsync()) {
820 auto& memory_manager{gpu.MemoryManager()}; 809 gpu_memory.Write<u32>(addr, value);
821 memory_manager.Write<u32>(addr, value);
822 return; 810 return;
823 } 811 }
824 fence_manager.SignalSemaphore(addr, value); 812 fence_manager.SignalSemaphore(addr, value);
825} 813}
826 814
827void RasterizerOpenGL::SignalSyncPoint(u32 value) { 815void RasterizerOpenGL::SignalSyncPoint(u32 value) {
828 auto& gpu{system.GPU()};
829 if (!gpu.IsAsync()) { 816 if (!gpu.IsAsync()) {
830 gpu.IncrementSyncPoint(value); 817 gpu.IncrementSyncPoint(value);
831 return; 818 return;
@@ -834,7 +821,6 @@ void RasterizerOpenGL::SignalSyncPoint(u32 value) {
834} 821}
835 822
836void RasterizerOpenGL::ReleaseFences() { 823void RasterizerOpenGL::ReleaseFences() {
837 auto& gpu{system.GPU()};
838 if (!gpu.IsAsync()) { 824 if (!gpu.IsAsync()) {
839 return; 825 return;
840 } 826 }
@@ -920,7 +906,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh
920 GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV}; 906 GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV};
921 907
922 MICROPROFILE_SCOPE(OpenGL_UBO); 908 MICROPROFILE_SCOPE(OpenGL_UBO);
923 const auto& stages = system.GPU().Maxwell3D().state.shader_stages; 909 const auto& stages = maxwell3d.state.shader_stages;
924 const auto& shader_stage = stages[stage_index]; 910 const auto& shader_stage = stages[stage_index];
925 const auto& entries = shader->GetEntries(); 911 const auto& entries = shader->GetEntries();
926 const bool use_unified = entries.use_unified_uniforms; 912 const bool use_unified = entries.use_unified_uniforms;
@@ -945,7 +931,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh
945 931
946void RasterizerOpenGL::SetupComputeConstBuffers(Shader* kernel) { 932void RasterizerOpenGL::SetupComputeConstBuffers(Shader* kernel) {
947 MICROPROFILE_SCOPE(OpenGL_UBO); 933 MICROPROFILE_SCOPE(OpenGL_UBO);
948 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 934 const auto& launch_desc = kepler_compute.launch_description;
949 const auto& entries = kernel->GetEntries(); 935 const auto& entries = kernel->GetEntries();
950 const bool use_unified = entries.use_unified_uniforms; 936 const bool use_unified = entries.use_unified_uniforms;
951 937
@@ -1018,9 +1004,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
1018 GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV, 1004 GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV,
1019 }; 1005 };
1020 1006
1021 auto& gpu{system.GPU()}; 1007 const auto& cbufs{maxwell3d.state.shader_stages[stage_index]};
1022 auto& memory_manager{gpu.MemoryManager()};
1023 const auto& cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]};
1024 const auto& entries{shader->GetEntries().global_memory_entries}; 1008 const auto& entries{shader->GetEntries().global_memory_entries};
1025 1009
1026 std::array<GLuint64EXT, 32> pointers; 1010 std::array<GLuint64EXT, 32> pointers;
@@ -1030,8 +1014,8 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
1030 u32 binding = assembly_shaders ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer; 1014 u32 binding = assembly_shaders ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer;
1031 for (const auto& entry : entries) { 1015 for (const auto& entry : entries) {
1032 const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset}; 1016 const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset};
1033 const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; 1017 const GPUVAddr gpu_addr{gpu_memory.Read<u64>(addr)};
1034 const u32 size{memory_manager.Read<u32>(addr + 8)}; 1018 const u32 size{gpu_memory.Read<u32>(addr + 8)};
1035 SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); 1019 SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]);
1036 ++binding; 1020 ++binding;
1037 } 1021 }
@@ -1041,9 +1025,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh
1041} 1025}
1042 1026
1043void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { 1027void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
1044 auto& gpu{system.GPU()}; 1028 const auto& cbufs{kepler_compute.launch_description.const_buffer_config};
1045 auto& memory_manager{gpu.MemoryManager()};
1046 const auto& cbufs{gpu.KeplerCompute().launch_description.const_buffer_config};
1047 const auto& entries{kernel->GetEntries().global_memory_entries}; 1029 const auto& entries{kernel->GetEntries().global_memory_entries};
1048 1030
1049 std::array<GLuint64EXT, 32> pointers; 1031 std::array<GLuint64EXT, 32> pointers;
@@ -1052,8 +1034,8 @@ void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) {
1052 u32 binding = 0; 1034 u32 binding = 0;
1053 for (const auto& entry : entries) { 1035 for (const auto& entry : entries) {
1054 const GPUVAddr addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset}; 1036 const GPUVAddr addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset};
1055 const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; 1037 const GPUVAddr gpu_addr{gpu_memory.Read<u64>(addr)};
1056 const u32 size{memory_manager.Read<u32>(addr + 8)}; 1038 const u32 size{gpu_memory.Read<u32>(addr + 8)};
1057 SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); 1039 SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]);
1058 ++binding; 1040 ++binding;
1059 } 1041 }
@@ -1077,7 +1059,6 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e
1077 1059
1078void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) { 1060void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) {
1079 MICROPROFILE_SCOPE(OpenGL_Texture); 1061 MICROPROFILE_SCOPE(OpenGL_Texture);
1080 const auto& maxwell3d = system.GPU().Maxwell3D();
1081 u32 binding = device.GetBaseBindings(stage_index).sampler; 1062 u32 binding = device.GetBaseBindings(stage_index).sampler;
1082 for (const auto& entry : shader->GetEntries().samplers) { 1063 for (const auto& entry : shader->GetEntries().samplers) {
1083 const auto shader_type = static_cast<ShaderType>(stage_index); 1064 const auto shader_type = static_cast<ShaderType>(stage_index);
@@ -1090,11 +1071,10 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader
1090 1071
1091void RasterizerOpenGL::SetupComputeTextures(Shader* kernel) { 1072void RasterizerOpenGL::SetupComputeTextures(Shader* kernel) {
1092 MICROPROFILE_SCOPE(OpenGL_Texture); 1073 MICROPROFILE_SCOPE(OpenGL_Texture);
1093 const auto& compute = system.GPU().KeplerCompute();
1094 u32 binding = 0; 1074 u32 binding = 0;
1095 for (const auto& entry : kernel->GetEntries().samplers) { 1075 for (const auto& entry : kernel->GetEntries().samplers) {
1096 for (std::size_t i = 0; i < entry.size; ++i) { 1076 for (std::size_t i = 0; i < entry.size; ++i) {
1097 const auto texture = GetTextureInfo(compute, entry, ShaderType::Compute, i); 1077 const auto texture = GetTextureInfo(kepler_compute, entry, ShaderType::Compute, i);
1098 SetupTexture(binding++, texture, entry); 1078 SetupTexture(binding++, texture, entry);
1099 } 1079 }
1100 } 1080 }
@@ -1118,20 +1098,18 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu
1118} 1098}
1119 1099
1120void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, Shader* shader) { 1100void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, Shader* shader) {
1121 const auto& maxwell3d = system.GPU().Maxwell3D();
1122 u32 binding = device.GetBaseBindings(stage_index).image; 1101 u32 binding = device.GetBaseBindings(stage_index).image;
1123 for (const auto& entry : shader->GetEntries().images) { 1102 for (const auto& entry : shader->GetEntries().images) {
1124 const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index); 1103 const auto shader_type = static_cast<ShaderType>(stage_index);
1125 const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic; 1104 const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic;
1126 SetupImage(binding++, tic, entry); 1105 SetupImage(binding++, tic, entry);
1127 } 1106 }
1128} 1107}
1129 1108
1130void RasterizerOpenGL::SetupComputeImages(Shader* shader) { 1109void RasterizerOpenGL::SetupComputeImages(Shader* shader) {
1131 const auto& compute = system.GPU().KeplerCompute();
1132 u32 binding = 0; 1110 u32 binding = 0;
1133 for (const auto& entry : shader->GetEntries().images) { 1111 for (const auto& entry : shader->GetEntries().images) {
1134 const auto tic = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute).tic; 1112 const auto tic = GetTextureInfo(kepler_compute, entry, ShaderType::Compute).tic;
1135 SetupImage(binding++, tic, entry); 1113 SetupImage(binding++, tic, entry);
1136 } 1114 }
1137} 1115}
@@ -1151,9 +1129,8 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
1151} 1129}
1152 1130
1153void RasterizerOpenGL::SyncViewport() { 1131void RasterizerOpenGL::SyncViewport() {
1154 auto& gpu = system.GPU().Maxwell3D(); 1132 auto& flags = maxwell3d.dirty.flags;
1155 auto& flags = gpu.dirty.flags; 1133 const auto& regs = maxwell3d.regs;
1156 const auto& regs = gpu.regs;
1157 1134
1158 const bool dirty_viewport = flags[Dirty::Viewports]; 1135 const bool dirty_viewport = flags[Dirty::Viewports];
1159 const bool dirty_clip_control = flags[Dirty::ClipControl]; 1136 const bool dirty_clip_control = flags[Dirty::ClipControl];
@@ -1225,25 +1202,23 @@ void RasterizerOpenGL::SyncViewport() {
1225} 1202}
1226 1203
1227void RasterizerOpenGL::SyncDepthClamp() { 1204void RasterizerOpenGL::SyncDepthClamp() {
1228 auto& gpu = system.GPU().Maxwell3D(); 1205 auto& flags = maxwell3d.dirty.flags;
1229 auto& flags = gpu.dirty.flags;
1230 if (!flags[Dirty::DepthClampEnabled]) { 1206 if (!flags[Dirty::DepthClampEnabled]) {
1231 return; 1207 return;
1232 } 1208 }
1233 flags[Dirty::DepthClampEnabled] = false; 1209 flags[Dirty::DepthClampEnabled] = false;
1234 1210
1235 oglEnable(GL_DEPTH_CLAMP, gpu.regs.view_volume_clip_control.depth_clamp_disabled == 0); 1211 oglEnable(GL_DEPTH_CLAMP, maxwell3d.regs.view_volume_clip_control.depth_clamp_disabled == 0);
1236} 1212}
1237 1213
1238void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { 1214void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
1239 auto& gpu = system.GPU().Maxwell3D(); 1215 auto& flags = maxwell3d.dirty.flags;
1240 auto& flags = gpu.dirty.flags;
1241 if (!flags[Dirty::ClipDistances] && !flags[Dirty::Shaders]) { 1216 if (!flags[Dirty::ClipDistances] && !flags[Dirty::Shaders]) {
1242 return; 1217 return;
1243 } 1218 }
1244 flags[Dirty::ClipDistances] = false; 1219 flags[Dirty::ClipDistances] = false;
1245 1220
1246 clip_mask &= gpu.regs.clip_distance_enabled; 1221 clip_mask &= maxwell3d.regs.clip_distance_enabled;
1247 if (clip_mask == last_clip_distance_mask) { 1222 if (clip_mask == last_clip_distance_mask) {
1248 return; 1223 return;
1249 } 1224 }
@@ -1259,9 +1234,8 @@ void RasterizerOpenGL::SyncClipCoef() {
1259} 1234}
1260 1235
1261void RasterizerOpenGL::SyncCullMode() { 1236void RasterizerOpenGL::SyncCullMode() {
1262 auto& gpu = system.GPU().Maxwell3D(); 1237 auto& flags = maxwell3d.dirty.flags;
1263 auto& flags = gpu.dirty.flags; 1238 const auto& regs = maxwell3d.regs;
1264 const auto& regs = gpu.regs;
1265 1239
1266 if (flags[Dirty::CullTest]) { 1240 if (flags[Dirty::CullTest]) {
1267 flags[Dirty::CullTest] = false; 1241 flags[Dirty::CullTest] = false;
@@ -1276,26 +1250,24 @@ void RasterizerOpenGL::SyncCullMode() {
1276} 1250}
1277 1251
1278void RasterizerOpenGL::SyncPrimitiveRestart() { 1252void RasterizerOpenGL::SyncPrimitiveRestart() {
1279 auto& gpu = system.GPU().Maxwell3D(); 1253 auto& flags = maxwell3d.dirty.flags;
1280 auto& flags = gpu.dirty.flags;
1281 if (!flags[Dirty::PrimitiveRestart]) { 1254 if (!flags[Dirty::PrimitiveRestart]) {
1282 return; 1255 return;
1283 } 1256 }
1284 flags[Dirty::PrimitiveRestart] = false; 1257 flags[Dirty::PrimitiveRestart] = false;
1285 1258
1286 if (gpu.regs.primitive_restart.enabled) { 1259 if (maxwell3d.regs.primitive_restart.enabled) {
1287 glEnable(GL_PRIMITIVE_RESTART); 1260 glEnable(GL_PRIMITIVE_RESTART);
1288 glPrimitiveRestartIndex(gpu.regs.primitive_restart.index); 1261 glPrimitiveRestartIndex(maxwell3d.regs.primitive_restart.index);
1289 } else { 1262 } else {
1290 glDisable(GL_PRIMITIVE_RESTART); 1263 glDisable(GL_PRIMITIVE_RESTART);
1291 } 1264 }
1292} 1265}
1293 1266
1294void RasterizerOpenGL::SyncDepthTestState() { 1267void RasterizerOpenGL::SyncDepthTestState() {
1295 auto& gpu = system.GPU().Maxwell3D(); 1268 auto& flags = maxwell3d.dirty.flags;
1296 auto& flags = gpu.dirty.flags; 1269 const auto& regs = maxwell3d.regs;
1297 1270
1298 const auto& regs = gpu.regs;
1299 if (flags[Dirty::DepthMask]) { 1271 if (flags[Dirty::DepthMask]) {
1300 flags[Dirty::DepthMask] = false; 1272 flags[Dirty::DepthMask] = false;
1301 glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE); 1273 glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE);
@@ -1313,14 +1285,13 @@ void RasterizerOpenGL::SyncDepthTestState() {
1313} 1285}
1314 1286
1315void RasterizerOpenGL::SyncStencilTestState() { 1287void RasterizerOpenGL::SyncStencilTestState() {
1316 auto& gpu = system.GPU().Maxwell3D(); 1288 auto& flags = maxwell3d.dirty.flags;
1317 auto& flags = gpu.dirty.flags;
1318 if (!flags[Dirty::StencilTest]) { 1289 if (!flags[Dirty::StencilTest]) {
1319 return; 1290 return;
1320 } 1291 }
1321 flags[Dirty::StencilTest] = false; 1292 flags[Dirty::StencilTest] = false;
1322 1293
1323 const auto& regs = gpu.regs; 1294 const auto& regs = maxwell3d.regs;
1324 oglEnable(GL_STENCIL_TEST, regs.stencil_enable); 1295 oglEnable(GL_STENCIL_TEST, regs.stencil_enable);
1325 1296
1326 glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), 1297 glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func),
@@ -1345,25 +1316,24 @@ void RasterizerOpenGL::SyncStencilTestState() {
1345} 1316}
1346 1317
1347void RasterizerOpenGL::SyncRasterizeEnable() { 1318void RasterizerOpenGL::SyncRasterizeEnable() {
1348 auto& gpu = system.GPU().Maxwell3D(); 1319 auto& flags = maxwell3d.dirty.flags;
1349 auto& flags = gpu.dirty.flags;
1350 if (!flags[Dirty::RasterizeEnable]) { 1320 if (!flags[Dirty::RasterizeEnable]) {
1351 return; 1321 return;
1352 } 1322 }
1353 flags[Dirty::RasterizeEnable] = false; 1323 flags[Dirty::RasterizeEnable] = false;
1354 1324
1355 oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0); 1325 oglEnable(GL_RASTERIZER_DISCARD, maxwell3d.regs.rasterize_enable == 0);
1356} 1326}
1357 1327
1358void RasterizerOpenGL::SyncPolygonModes() { 1328void RasterizerOpenGL::SyncPolygonModes() {
1359 auto& gpu = system.GPU().Maxwell3D(); 1329 auto& flags = maxwell3d.dirty.flags;
1360 auto& flags = gpu.dirty.flags;
1361 if (!flags[Dirty::PolygonModes]) { 1330 if (!flags[Dirty::PolygonModes]) {
1362 return; 1331 return;
1363 } 1332 }
1364 flags[Dirty::PolygonModes] = false; 1333 flags[Dirty::PolygonModes] = false;
1365 1334
1366 if (gpu.regs.fill_rectangle) { 1335 const auto& regs = maxwell3d.regs;
1336 if (regs.fill_rectangle) {
1367 if (!GLAD_GL_NV_fill_rectangle) { 1337 if (!GLAD_GL_NV_fill_rectangle) {
1368 LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); 1338 LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
1369 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 1339 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -1376,27 +1346,26 @@ void RasterizerOpenGL::SyncPolygonModes() {
1376 return; 1346 return;
1377 } 1347 }
1378 1348
1379 if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) { 1349 if (regs.polygon_mode_front == regs.polygon_mode_back) {
1380 flags[Dirty::PolygonModeFront] = false; 1350 flags[Dirty::PolygonModeFront] = false;
1381 flags[Dirty::PolygonModeBack] = false; 1351 flags[Dirty::PolygonModeBack] = false;
1382 glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); 1352 glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(regs.polygon_mode_front));
1383 return; 1353 return;
1384 } 1354 }
1385 1355
1386 if (flags[Dirty::PolygonModeFront]) { 1356 if (flags[Dirty::PolygonModeFront]) {
1387 flags[Dirty::PolygonModeFront] = false; 1357 flags[Dirty::PolygonModeFront] = false;
1388 glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); 1358 glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(regs.polygon_mode_front));
1389 } 1359 }
1390 1360
1391 if (flags[Dirty::PolygonModeBack]) { 1361 if (flags[Dirty::PolygonModeBack]) {
1392 flags[Dirty::PolygonModeBack] = false; 1362 flags[Dirty::PolygonModeBack] = false;
1393 glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back)); 1363 glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(regs.polygon_mode_back));
1394 } 1364 }
1395} 1365}
1396 1366
1397void RasterizerOpenGL::SyncColorMask() { 1367void RasterizerOpenGL::SyncColorMask() {
1398 auto& gpu = system.GPU().Maxwell3D(); 1368 auto& flags = maxwell3d.dirty.flags;
1399 auto& flags = gpu.dirty.flags;
1400 if (!flags[Dirty::ColorMasks]) { 1369 if (!flags[Dirty::ColorMasks]) {
1401 return; 1370 return;
1402 } 1371 }
@@ -1405,7 +1374,7 @@ void RasterizerOpenGL::SyncColorMask() {
1405 const bool force = flags[Dirty::ColorMaskCommon]; 1374 const bool force = flags[Dirty::ColorMaskCommon];
1406 flags[Dirty::ColorMaskCommon] = false; 1375 flags[Dirty::ColorMaskCommon] = false;
1407 1376
1408 const auto& regs = gpu.regs; 1377 const auto& regs = maxwell3d.regs;
1409 if (regs.color_mask_common) { 1378 if (regs.color_mask_common) {
1410 if (!force && !flags[Dirty::ColorMask0]) { 1379 if (!force && !flags[Dirty::ColorMask0]) {
1411 return; 1380 return;
@@ -1430,33 +1399,30 @@ void RasterizerOpenGL::SyncColorMask() {
1430} 1399}
1431 1400
1432void RasterizerOpenGL::SyncMultiSampleState() { 1401void RasterizerOpenGL::SyncMultiSampleState() {
1433 auto& gpu = system.GPU().Maxwell3D(); 1402 auto& flags = maxwell3d.dirty.flags;
1434 auto& flags = gpu.dirty.flags;
1435 if (!flags[Dirty::MultisampleControl]) { 1403 if (!flags[Dirty::MultisampleControl]) {
1436 return; 1404 return;
1437 } 1405 }
1438 flags[Dirty::MultisampleControl] = false; 1406 flags[Dirty::MultisampleControl] = false;
1439 1407
1440 const auto& regs = system.GPU().Maxwell3D().regs; 1408 const auto& regs = maxwell3d.regs;
1441 oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); 1409 oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage);
1442 oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); 1410 oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one);
1443} 1411}
1444 1412
1445void RasterizerOpenGL::SyncFragmentColorClampState() { 1413void RasterizerOpenGL::SyncFragmentColorClampState() {
1446 auto& gpu = system.GPU().Maxwell3D(); 1414 auto& flags = maxwell3d.dirty.flags;
1447 auto& flags = gpu.dirty.flags;
1448 if (!flags[Dirty::FragmentClampColor]) { 1415 if (!flags[Dirty::FragmentClampColor]) {
1449 return; 1416 return;
1450 } 1417 }
1451 flags[Dirty::FragmentClampColor] = false; 1418 flags[Dirty::FragmentClampColor] = false;
1452 1419
1453 glClampColor(GL_CLAMP_FRAGMENT_COLOR, gpu.regs.frag_color_clamp ? GL_TRUE : GL_FALSE); 1420 glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d.regs.frag_color_clamp ? GL_TRUE : GL_FALSE);
1454} 1421}
1455 1422
1456void RasterizerOpenGL::SyncBlendState() { 1423void RasterizerOpenGL::SyncBlendState() {
1457 auto& gpu = system.GPU().Maxwell3D(); 1424 auto& flags = maxwell3d.dirty.flags;
1458 auto& flags = gpu.dirty.flags; 1425 const auto& regs = maxwell3d.regs;
1459 const auto& regs = gpu.regs;
1460 1426
1461 if (flags[Dirty::BlendColor]) { 1427 if (flags[Dirty::BlendColor]) {
1462 flags[Dirty::BlendColor] = false; 1428 flags[Dirty::BlendColor] = false;
@@ -1513,14 +1479,13 @@ void RasterizerOpenGL::SyncBlendState() {
1513} 1479}
1514 1480
1515void RasterizerOpenGL::SyncLogicOpState() { 1481void RasterizerOpenGL::SyncLogicOpState() {
1516 auto& gpu = system.GPU().Maxwell3D(); 1482 auto& flags = maxwell3d.dirty.flags;
1517 auto& flags = gpu.dirty.flags;
1518 if (!flags[Dirty::LogicOp]) { 1483 if (!flags[Dirty::LogicOp]) {
1519 return; 1484 return;
1520 } 1485 }
1521 flags[Dirty::LogicOp] = false; 1486 flags[Dirty::LogicOp] = false;
1522 1487
1523 const auto& regs = gpu.regs; 1488 const auto& regs = maxwell3d.regs;
1524 if (regs.logic_op.enable) { 1489 if (regs.logic_op.enable) {
1525 glEnable(GL_COLOR_LOGIC_OP); 1490 glEnable(GL_COLOR_LOGIC_OP);
1526 glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); 1491 glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation));
@@ -1530,14 +1495,13 @@ void RasterizerOpenGL::SyncLogicOpState() {
1530} 1495}
1531 1496
1532void RasterizerOpenGL::SyncScissorTest() { 1497void RasterizerOpenGL::SyncScissorTest() {
1533 auto& gpu = system.GPU().Maxwell3D(); 1498 auto& flags = maxwell3d.dirty.flags;
1534 auto& flags = gpu.dirty.flags;
1535 if (!flags[Dirty::Scissors]) { 1499 if (!flags[Dirty::Scissors]) {
1536 return; 1500 return;
1537 } 1501 }
1538 flags[Dirty::Scissors] = false; 1502 flags[Dirty::Scissors] = false;
1539 1503
1540 const auto& regs = gpu.regs; 1504 const auto& regs = maxwell3d.regs;
1541 for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { 1505 for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) {
1542 if (!flags[Dirty::Scissor0 + index]) { 1506 if (!flags[Dirty::Scissor0 + index]) {
1543 continue; 1507 continue;
@@ -1556,16 +1520,15 @@ void RasterizerOpenGL::SyncScissorTest() {
1556} 1520}
1557 1521
1558void RasterizerOpenGL::SyncPointState() { 1522void RasterizerOpenGL::SyncPointState() {
1559 auto& gpu = system.GPU().Maxwell3D(); 1523 auto& flags = maxwell3d.dirty.flags;
1560 auto& flags = gpu.dirty.flags;
1561 if (!flags[Dirty::PointSize]) { 1524 if (!flags[Dirty::PointSize]) {
1562 return; 1525 return;
1563 } 1526 }
1564 flags[Dirty::PointSize] = false; 1527 flags[Dirty::PointSize] = false;
1565 1528
1566 oglEnable(GL_POINT_SPRITE, gpu.regs.point_sprite_enable); 1529 oglEnable(GL_POINT_SPRITE, maxwell3d.regs.point_sprite_enable);
1567 1530
1568 if (gpu.regs.vp_point_size.enable) { 1531 if (maxwell3d.regs.vp_point_size.enable) {
1569 // By definition of GL_POINT_SIZE, it only matters if GL_PROGRAM_POINT_SIZE is disabled. 1532 // By definition of GL_POINT_SIZE, it only matters if GL_PROGRAM_POINT_SIZE is disabled.
1570 glEnable(GL_PROGRAM_POINT_SIZE); 1533 glEnable(GL_PROGRAM_POINT_SIZE);
1571 return; 1534 return;
@@ -1573,32 +1536,30 @@ void RasterizerOpenGL::SyncPointState() {
1573 1536
1574 // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid 1537 // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid
1575 // in OpenGL). 1538 // in OpenGL).
1576 glPointSize(std::max(1.0f, gpu.regs.point_size)); 1539 glPointSize(std::max(1.0f, maxwell3d.regs.point_size));
1577 glDisable(GL_PROGRAM_POINT_SIZE); 1540 glDisable(GL_PROGRAM_POINT_SIZE);
1578} 1541}
1579 1542
1580void RasterizerOpenGL::SyncLineState() { 1543void RasterizerOpenGL::SyncLineState() {
1581 auto& gpu = system.GPU().Maxwell3D(); 1544 auto& flags = maxwell3d.dirty.flags;
1582 auto& flags = gpu.dirty.flags;
1583 if (!flags[Dirty::LineWidth]) { 1545 if (!flags[Dirty::LineWidth]) {
1584 return; 1546 return;
1585 } 1547 }
1586 flags[Dirty::LineWidth] = false; 1548 flags[Dirty::LineWidth] = false;
1587 1549
1588 const auto& regs = gpu.regs; 1550 const auto& regs = maxwell3d.regs;
1589 oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable); 1551 oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable);
1590 glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased); 1552 glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased);
1591} 1553}
1592 1554
1593void RasterizerOpenGL::SyncPolygonOffset() { 1555void RasterizerOpenGL::SyncPolygonOffset() {
1594 auto& gpu = system.GPU().Maxwell3D(); 1556 auto& flags = maxwell3d.dirty.flags;
1595 auto& flags = gpu.dirty.flags;
1596 if (!flags[Dirty::PolygonOffset]) { 1557 if (!flags[Dirty::PolygonOffset]) {
1597 return; 1558 return;
1598 } 1559 }
1599 flags[Dirty::PolygonOffset] = false; 1560 flags[Dirty::PolygonOffset] = false;
1600 1561
1601 const auto& regs = gpu.regs; 1562 const auto& regs = maxwell3d.regs;
1602 oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable); 1563 oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable);
1603 oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable); 1564 oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable);
1604 oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); 1565 oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable);
@@ -1612,14 +1573,13 @@ void RasterizerOpenGL::SyncPolygonOffset() {
1612} 1573}
1613 1574
1614void RasterizerOpenGL::SyncAlphaTest() { 1575void RasterizerOpenGL::SyncAlphaTest() {
1615 auto& gpu = system.GPU().Maxwell3D(); 1576 auto& flags = maxwell3d.dirty.flags;
1616 auto& flags = gpu.dirty.flags;
1617 if (!flags[Dirty::AlphaTest]) { 1577 if (!flags[Dirty::AlphaTest]) {
1618 return; 1578 return;
1619 } 1579 }
1620 flags[Dirty::AlphaTest] = false; 1580 flags[Dirty::AlphaTest] = false;
1621 1581
1622 const auto& regs = gpu.regs; 1582 const auto& regs = maxwell3d.regs;
1623 if (regs.alpha_test_enabled && regs.rt_control.count > 1) { 1583 if (regs.alpha_test_enabled && regs.rt_control.count > 1) {
1624 LOG_WARNING(Render_OpenGL, "Alpha testing with more than one render target is not tested"); 1584 LOG_WARNING(Render_OpenGL, "Alpha testing with more than one render target is not tested");
1625 } 1585 }
@@ -1633,20 +1593,19 @@ void RasterizerOpenGL::SyncAlphaTest() {
1633} 1593}
1634 1594
1635void RasterizerOpenGL::SyncFramebufferSRGB() { 1595void RasterizerOpenGL::SyncFramebufferSRGB() {
1636 auto& gpu = system.GPU().Maxwell3D(); 1596 auto& flags = maxwell3d.dirty.flags;
1637 auto& flags = gpu.dirty.flags;
1638 if (!flags[Dirty::FramebufferSRGB]) { 1597 if (!flags[Dirty::FramebufferSRGB]) {
1639 return; 1598 return;
1640 } 1599 }
1641 flags[Dirty::FramebufferSRGB] = false; 1600 flags[Dirty::FramebufferSRGB] = false;
1642 1601
1643 oglEnable(GL_FRAMEBUFFER_SRGB, gpu.regs.framebuffer_srgb); 1602 oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d.regs.framebuffer_srgb);
1644} 1603}
1645 1604
1646void RasterizerOpenGL::SyncTransformFeedback() { 1605void RasterizerOpenGL::SyncTransformFeedback() {
1647 // TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal 1606 // TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal
1648 // when this is required. 1607 // when this is required.
1649 const auto& regs = system.GPU().Maxwell3D().regs; 1608 const auto& regs = maxwell3d.regs;
1650 1609
1651 static constexpr std::size_t STRIDE = 3; 1610 static constexpr std::size_t STRIDE = 3;
1652 std::array<GLint, 128 * STRIDE * Maxwell::NumTransformFeedbackBuffers> attribs; 1611 std::array<GLint, 128 * STRIDE * Maxwell::NumTransformFeedbackBuffers> attribs;
@@ -1698,7 +1657,7 @@ void RasterizerOpenGL::SyncTransformFeedback() {
1698} 1657}
1699 1658
1700void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) { 1659void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) {
1701 const auto& regs = system.GPU().Maxwell3D().regs; 1660 const auto& regs = maxwell3d.regs;
1702 if (regs.tfb_enabled == 0) { 1661 if (regs.tfb_enabled == 0) {
1703 return; 1662 return;
1704 } 1663 }
@@ -1741,7 +1700,7 @@ void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) {
1741} 1700}
1742 1701
1743void RasterizerOpenGL::EndTransformFeedback() { 1702void RasterizerOpenGL::EndTransformFeedback() {
1744 const auto& regs = system.GPU().Maxwell3D().regs; 1703 const auto& regs = maxwell3d.regs;
1745 if (regs.tfb_enabled == 0) { 1704 if (regs.tfb_enabled == 0) {
1746 return; 1705 return;
1747 } 1706 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index ccc6f50f6..f451404b2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -36,8 +36,8 @@
36#include "video_core/shader/async_shaders.h" 36#include "video_core/shader/async_shaders.h"
37#include "video_core/textures/texture.h" 37#include "video_core/textures/texture.h"
38 38
39namespace Core { 39namespace Core::Memory {
40class System; 40class Memory;
41} 41}
42 42
43namespace Core::Frontend { 43namespace Core::Frontend {
@@ -55,9 +55,10 @@ struct DrawParameters;
55 55
56class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { 56class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
57public: 57public:
58 explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 58 explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
59 const Device& device, ScreenInfo& info, 59 Core::Memory::Memory& cpu_memory, const Device& device,
60 ProgramManager& program_manager, StateTracker& state_tracker); 60 ScreenInfo& screen_info, ProgramManager& program_manager,
61 StateTracker& state_tracker);
61 ~RasterizerOpenGL() override; 62 ~RasterizerOpenGL() override;
62 63
63 void Draw(bool is_indexed, bool is_instanced) override; 64 void Draw(bool is_indexed, bool is_instanced) override;
@@ -83,9 +84,8 @@ public:
83 const Tegra::Engines::Fermi2D::Config& copy_config) override; 84 const Tegra::Engines::Fermi2D::Config& copy_config) override;
84 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 85 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
85 u32 pixel_stride) override; 86 u32 pixel_stride) override;
86 void LoadDiskResources(const std::atomic_bool& stop_loading, 87 void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
87 const VideoCore::DiskResourceLoadCallback& callback) override; 88 const VideoCore::DiskResourceLoadCallback& callback) override;
88 void SetupDirtyFlags() override;
89 89
90 /// Returns true when there are commands queued to the OpenGL server. 90 /// Returns true when there are commands queued to the OpenGL server.
91 bool AnyCommandQueued() const { 91 bool AnyCommandQueued() const {
@@ -237,7 +237,15 @@ private:
237 237
238 void SetupShaders(GLenum primitive_mode); 238 void SetupShaders(GLenum primitive_mode);
239 239
240 Tegra::GPU& gpu;
241 Tegra::Engines::Maxwell3D& maxwell3d;
242 Tegra::Engines::KeplerCompute& kepler_compute;
243 Tegra::MemoryManager& gpu_memory;
244
240 const Device& device; 245 const Device& device;
246 ScreenInfo& screen_info;
247 ProgramManager& program_manager;
248 StateTracker& state_tracker;
241 249
242 TextureCacheOpenGL texture_cache; 250 TextureCacheOpenGL texture_cache;
243 ShaderCacheOpenGL shader_cache; 251 ShaderCacheOpenGL shader_cache;
@@ -247,10 +255,6 @@ private:
247 OGLBufferCache buffer_cache; 255 OGLBufferCache buffer_cache;
248 FenceManagerOpenGL fence_manager; 256 FenceManagerOpenGL fence_manager;
249 257
250 Core::System& system;
251 ScreenInfo& screen_info;
252 ProgramManager& program_manager;
253 StateTracker& state_tracker;
254 VideoCommon::Shader::AsyncShaders async_shaders; 258 VideoCommon::Shader::AsyncShaders async_shaders;
255 259
256 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 260 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index a07d56ef0..bd56bed0c 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -239,12 +239,11 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory(
239 ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) { 239 ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) {
240 const auto shader_type = GetShaderType(program_type); 240 const auto shader_type = GetShaderType(program_type);
241 241
242 auto& gpu = params.system.GPU(); 242 auto& gpu = params.gpu;
243 gpu.ShaderNotify().MarkSharderBuilding(); 243 gpu.ShaderNotify().MarkSharderBuilding();
244 244
245 auto registry = std::make_shared<Registry>(shader_type, gpu.Maxwell3D()); 245 auto registry = std::make_shared<Registry>(shader_type, gpu.Maxwell3D());
246 if (!async_shaders.IsShaderAsync(params.system.GPU()) || 246 if (!async_shaders.IsShaderAsync(gpu) || !params.device.UseAsynchronousShaders()) {
247 !params.device.UseAsynchronousShaders()) {
248 const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); 247 const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry);
249 // TODO(Rodrigo): Handle VertexA shaders 248 // TODO(Rodrigo): Handle VertexA shaders
250 // std::optional<ShaderIR> ir_b; 249 // std::optional<ShaderIR> ir_b;
@@ -287,11 +286,10 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory(
287 286
288std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params, 287std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params,
289 ProgramCode code) { 288 ProgramCode code) {
290 auto& gpu = params.system.GPU(); 289 auto& gpu = params.gpu;
291 gpu.ShaderNotify().MarkSharderBuilding(); 290 gpu.ShaderNotify().MarkSharderBuilding();
292 291
293 auto& engine = gpu.KeplerCompute(); 292 auto registry = std::make_shared<Registry>(ShaderType::Compute, params.engine);
294 auto registry = std::make_shared<Registry>(ShaderType::Compute, engine);
295 const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); 293 const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry);
296 const u64 uid = params.unique_identifier; 294 const u64 uid = params.unique_identifier;
297 auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); 295 auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry);
@@ -320,15 +318,20 @@ std::unique_ptr<Shader> Shader::CreateFromCache(const ShaderParameters& params,
320 precompiled_shader.registry, precompiled_shader.entries, precompiled_shader.program)); 318 precompiled_shader.registry, precompiled_shader.entries, precompiled_shader.program));
321} 319}
322 320
323ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, 321ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer,
324 Core::Frontend::EmuWindow& emu_window, const Device& device) 322 Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
325 : VideoCommon::ShaderCache<Shader>{rasterizer}, system{system}, 323 Tegra::Engines::Maxwell3D& maxwell3d_,
326 emu_window{emu_window}, device{device}, disk_cache{system} {} 324 Tegra::Engines::KeplerCompute& kepler_compute_,
325 Tegra::MemoryManager& gpu_memory_, const Device& device_)
326 : VideoCommon::ShaderCache<Shader>{rasterizer}, emu_window{emu_window_}, gpu{gpu_},
327 gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_},
328 kepler_compute{kepler_compute_}, device{device_} {}
327 329
328ShaderCacheOpenGL::~ShaderCacheOpenGL() = default; 330ShaderCacheOpenGL::~ShaderCacheOpenGL() = default;
329 331
330void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, 332void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
331 const VideoCore::DiskResourceLoadCallback& callback) { 333 const VideoCore::DiskResourceLoadCallback& callback) {
334 disk_cache.BindTitleID(title_id);
332 const std::optional transferable = disk_cache.LoadTransferable(); 335 const std::optional transferable = disk_cache.LoadTransferable();
333 if (!transferable) { 336 if (!transferable) {
334 return; 337 return;
@@ -481,21 +484,19 @@ ProgramSharedPtr ShaderCacheOpenGL::GeneratePrecompiledProgram(
481 484
482Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program, 485Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
483 VideoCommon::Shader::AsyncShaders& async_shaders) { 486 VideoCommon::Shader::AsyncShaders& async_shaders) {
484 if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) { 487 if (!maxwell3d.dirty.flags[Dirty::Shaders]) {
485 auto* last_shader = last_shaders[static_cast<std::size_t>(program)]; 488 auto* last_shader = last_shaders[static_cast<std::size_t>(program)];
486 if (last_shader->IsBuilt()) { 489 if (last_shader->IsBuilt()) {
487 return last_shader; 490 return last_shader;
488 } 491 }
489 } 492 }
490 493
491 auto& memory_manager{system.GPU().MemoryManager()}; 494 const GPUVAddr address{GetShaderAddress(maxwell3d, program)};
492 const GPUVAddr address{GetShaderAddress(system, program)};
493 495
494 if (device.UseAsynchronousShaders() && async_shaders.HasCompletedWork()) { 496 if (device.UseAsynchronousShaders() && async_shaders.HasCompletedWork()) {
495 auto completed_work = async_shaders.GetCompletedWork(); 497 auto completed_work = async_shaders.GetCompletedWork();
496 for (auto& work : completed_work) { 498 for (auto& work : completed_work) {
497 Shader* shader = TryGet(work.cpu_address); 499 Shader* shader = TryGet(work.cpu_address);
498 auto& gpu = system.GPU();
499 gpu.ShaderNotify().MarkShaderComplete(); 500 gpu.ShaderNotify().MarkShaderComplete();
500 if (shader == nullptr) { 501 if (shader == nullptr) {
501 continue; 502 continue;
@@ -507,14 +508,13 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
507 shader->AsyncGLASMBuilt(std::move(work.program.glasm)); 508 shader->AsyncGLASMBuilt(std::move(work.program.glasm));
508 } 509 }
509 510
511 auto& registry = shader->GetRegistry();
512
510 ShaderDiskCacheEntry entry; 513 ShaderDiskCacheEntry entry;
511 entry.type = work.shader_type; 514 entry.type = work.shader_type;
512 entry.code = std::move(work.code); 515 entry.code = std::move(work.code);
513 entry.code_b = std::move(work.code_b); 516 entry.code_b = std::move(work.code_b);
514 entry.unique_identifier = work.uid; 517 entry.unique_identifier = work.uid;
515
516 auto& registry = shader->GetRegistry();
517
518 entry.bound_buffer = registry.GetBoundBuffer(); 518 entry.bound_buffer = registry.GetBoundBuffer();
519 entry.graphics_info = registry.GetGraphicsInfo(); 519 entry.graphics_info = registry.GetGraphicsInfo();
520 entry.keys = registry.GetKeys(); 520 entry.keys = registry.GetKeys();
@@ -525,28 +525,28 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
525 } 525 }
526 526
527 // Look up shader in the cache based on address 527 // Look up shader in the cache based on address
528 const auto cpu_addr{memory_manager.GpuToCpuAddress(address)}; 528 const std::optional<VAddr> cpu_addr{gpu_memory.GpuToCpuAddress(address)};
529 if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) { 529 if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) {
530 return last_shaders[static_cast<std::size_t>(program)] = shader; 530 return last_shaders[static_cast<std::size_t>(program)] = shader;
531 } 531 }
532 532
533 const auto host_ptr{memory_manager.GetPointer(address)}; 533 const u8* const host_ptr{gpu_memory.GetPointer(address)};
534 534
535 // No shader found - create a new one 535 // No shader found - create a new one
536 ProgramCode code{GetShaderCode(memory_manager, address, host_ptr, false)}; 536 ProgramCode code{GetShaderCode(gpu_memory, address, host_ptr, false)};
537 ProgramCode code_b; 537 ProgramCode code_b;
538 if (program == Maxwell::ShaderProgram::VertexA) { 538 if (program == Maxwell::ShaderProgram::VertexA) {
539 const GPUVAddr address_b{GetShaderAddress(system, Maxwell::ShaderProgram::VertexB)}; 539 const GPUVAddr address_b{GetShaderAddress(maxwell3d, Maxwell::ShaderProgram::VertexB)};
540 const u8* host_ptr_b = memory_manager.GetPointer(address_b); 540 const u8* host_ptr_b = gpu_memory.GetPointer(address_b);
541 code_b = GetShaderCode(memory_manager, address_b, host_ptr_b, false); 541 code_b = GetShaderCode(gpu_memory, address_b, host_ptr_b, false);
542 } 542 }
543 const std::size_t code_size = code.size() * sizeof(u64); 543 const std::size_t code_size = code.size() * sizeof(u64);
544 544
545 const u64 unique_identifier = GetUniqueIdentifier( 545 const u64 unique_identifier = GetUniqueIdentifier(
546 GetShaderType(program), program == Maxwell::ShaderProgram::VertexA, code, code_b); 546 GetShaderType(program), program == Maxwell::ShaderProgram::VertexA, code, code_b);
547 547
548 const ShaderParameters params{system, disk_cache, device, 548 const ShaderParameters params{gpu, maxwell3d, disk_cache, device,
549 *cpu_addr, host_ptr, unique_identifier}; 549 *cpu_addr, host_ptr, unique_identifier};
550 550
551 std::unique_ptr<Shader> shader; 551 std::unique_ptr<Shader> shader;
552 const auto found = runtime_cache.find(unique_identifier); 552 const auto found = runtime_cache.find(unique_identifier);
@@ -568,21 +568,20 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program,
568} 568}
569 569
570Shader* ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) { 570Shader* ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) {
571 auto& memory_manager{system.GPU().MemoryManager()}; 571 const std::optional<VAddr> cpu_addr{gpu_memory.GpuToCpuAddress(code_addr)};
572 const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)};
573 572
574 if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) { 573 if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) {
575 return kernel; 574 return kernel;
576 } 575 }
577 576
578 const auto host_ptr{memory_manager.GetPointer(code_addr)};
579 // No kernel found, create a new one 577 // No kernel found, create a new one
580 ProgramCode code{GetShaderCode(memory_manager, code_addr, host_ptr, true)}; 578 const u8* host_ptr{gpu_memory.GetPointer(code_addr)};
579 ProgramCode code{GetShaderCode(gpu_memory, code_addr, host_ptr, true)};
581 const std::size_t code_size{code.size() * sizeof(u64)}; 580 const std::size_t code_size{code.size() * sizeof(u64)};
582 const u64 unique_identifier{GetUniqueIdentifier(ShaderType::Compute, false, code)}; 581 const u64 unique_identifier{GetUniqueIdentifier(ShaderType::Compute, false, code)};
583 582
584 const ShaderParameters params{system, disk_cache, device, 583 const ShaderParameters params{gpu, kepler_compute, disk_cache, device,
585 *cpu_addr, host_ptr, unique_identifier}; 584 *cpu_addr, host_ptr, unique_identifier};
586 585
587 std::unique_ptr<Shader> kernel; 586 std::unique_ptr<Shader> kernel;
588 const auto found = runtime_cache.find(unique_identifier); 587 const auto found = runtime_cache.find(unique_identifier);
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 7528ac686..1708af06a 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -25,8 +25,8 @@
25#include "video_core/shader/shader_ir.h" 25#include "video_core/shader/shader_ir.h"
26#include "video_core/shader_cache.h" 26#include "video_core/shader_cache.h"
27 27
28namespace Core { 28namespace Tegra {
29class System; 29class MemoryManager;
30} 30}
31 31
32namespace Core::Frontend { 32namespace Core::Frontend {
@@ -57,11 +57,12 @@ struct PrecompiledShader {
57}; 57};
58 58
59struct ShaderParameters { 59struct ShaderParameters {
60 Core::System& system; 60 Tegra::GPU& gpu;
61 Tegra::Engines::ConstBufferEngineInterface& engine;
61 ShaderDiskCacheOpenGL& disk_cache; 62 ShaderDiskCacheOpenGL& disk_cache;
62 const Device& device; 63 const Device& device;
63 VAddr cpu_addr; 64 VAddr cpu_addr;
64 u8* host_ptr; 65 const u8* host_ptr;
65 u64 unique_identifier; 66 u64 unique_identifier;
66}; 67};
67 68
@@ -118,12 +119,14 @@ private:
118 119
119class ShaderCacheOpenGL final : public VideoCommon::ShaderCache<Shader> { 120class ShaderCacheOpenGL final : public VideoCommon::ShaderCache<Shader> {
120public: 121public:
121 explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, 122 explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::Frontend::EmuWindow& emu_window,
122 Core::Frontend::EmuWindow& emu_window, const Device& device); 123 Tegra::GPU& gpu, Tegra::Engines::Maxwell3D& maxwell3d,
124 Tegra::Engines::KeplerCompute& kepler_compute,
125 Tegra::MemoryManager& gpu_memory, const Device& device);
123 ~ShaderCacheOpenGL() override; 126 ~ShaderCacheOpenGL() override;
124 127
125 /// Loads disk cache for the current game 128 /// Loads disk cache for the current game
126 void LoadDiskCache(const std::atomic_bool& stop_loading, 129 void LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
127 const VideoCore::DiskResourceLoadCallback& callback); 130 const VideoCore::DiskResourceLoadCallback& callback);
128 131
129 /// Gets the current specified shader stage program 132 /// Gets the current specified shader stage program
@@ -138,9 +141,13 @@ private:
138 const ShaderDiskCacheEntry& entry, const ShaderDiskCachePrecompiled& precompiled_entry, 141 const ShaderDiskCacheEntry& entry, const ShaderDiskCachePrecompiled& precompiled_entry,
139 const std::unordered_set<GLenum>& supported_formats); 142 const std::unordered_set<GLenum>& supported_formats);
140 143
141 Core::System& system;
142 Core::Frontend::EmuWindow& emu_window; 144 Core::Frontend::EmuWindow& emu_window;
145 Tegra::GPU& gpu;
146 Tegra::MemoryManager& gpu_memory;
147 Tegra::Engines::Maxwell3D& maxwell3d;
148 Tegra::Engines::KeplerCompute& kepler_compute;
143 const Device& device; 149 const Device& device;
150
144 ShaderDiskCacheOpenGL disk_cache; 151 ShaderDiskCacheOpenGL disk_cache;
145 std::unordered_map<u64, PrecompiledShader> runtime_cache; 152 std::unordered_map<u64, PrecompiledShader> runtime_cache;
146 153
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
index 40c0877c1..166ee34e1 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -206,13 +206,17 @@ bool ShaderDiskCacheEntry::Save(Common::FS::IOFile& file) const {
206 flat_bindless_samplers.size(); 206 flat_bindless_samplers.size();
207} 207}
208 208
209ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL(Core::System& system) : system{system} {} 209ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL() = default;
210 210
211ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default; 211ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default;
212 212
213void ShaderDiskCacheOpenGL::BindTitleID(u64 title_id_) {
214 title_id = title_id_;
215}
216
213std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() { 217std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() {
214 // Skip games without title id 218 // Skip games without title id
215 const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0; 219 const bool has_title_id = title_id != 0;
216 if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) { 220 if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) {
217 return std::nullopt; 221 return std::nullopt;
218 } 222 }
@@ -474,7 +478,7 @@ std::string ShaderDiskCacheOpenGL::GetBaseDir() const {
474} 478}
475 479
476std::string ShaderDiskCacheOpenGL::GetTitleID() const { 480std::string ShaderDiskCacheOpenGL::GetTitleID() const {
477 return fmt::format("{:016X}", system.CurrentProcess()->GetTitleID()); 481 return fmt::format("{:016X}", title_id);
478} 482}
479 483
480} // namespace OpenGL 484} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
index db2bb73bc..aef841c1d 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
@@ -21,10 +21,6 @@
21#include "video_core/engines/shader_type.h" 21#include "video_core/engines/shader_type.h"
22#include "video_core/shader/registry.h" 22#include "video_core/shader/registry.h"
23 23
24namespace Core {
25class System;
26}
27
28namespace Common::FS { 24namespace Common::FS {
29class IOFile; 25class IOFile;
30} 26}
@@ -70,9 +66,12 @@ struct ShaderDiskCachePrecompiled {
70 66
71class ShaderDiskCacheOpenGL { 67class ShaderDiskCacheOpenGL {
72public: 68public:
73 explicit ShaderDiskCacheOpenGL(Core::System& system); 69 explicit ShaderDiskCacheOpenGL();
74 ~ShaderDiskCacheOpenGL(); 70 ~ShaderDiskCacheOpenGL();
75 71
72 /// Binds a title ID for all future operations.
73 void BindTitleID(u64 title_id);
74
76 /// Loads transferable cache. If file has a old version or on failure, it deletes the file. 75 /// Loads transferable cache. If file has a old version or on failure, it deletes the file.
77 std::optional<std::vector<ShaderDiskCacheEntry>> LoadTransferable(); 76 std::optional<std::vector<ShaderDiskCacheEntry>> LoadTransferable();
78 77
@@ -157,8 +156,6 @@ private:
157 return LoadArrayFromPrecompiled(&object, 1); 156 return LoadArrayFromPrecompiled(&object, 1);
158 } 157 }
159 158
160 Core::System& system;
161
162 // Stores whole precompiled cache which will be read from or saved to the precompiled chache 159 // Stores whole precompiled cache which will be read from or saved to the precompiled chache
163 // file 160 // file
164 FileSys::VectorVfsFile precompiled_cache_virtual_file; 161 FileSys::VectorVfsFile precompiled_cache_virtual_file;
@@ -168,8 +165,11 @@ private:
168 // Stored transferable shaders 165 // Stored transferable shaders
169 std::unordered_set<u64> stored_transferable; 166 std::unordered_set<u64> stored_transferable;
170 167
168 /// Title ID to operate on
169 u64 title_id = 0;
170
171 // The cache has been loaded at boot 171 // The cache has been loaded at boot
172 bool is_usable{}; 172 bool is_usable = false;
173}; 173};
174 174
175} // namespace OpenGL 175} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index d24fad3de..6bcf831f2 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -214,10 +214,8 @@ void SetupDirtyMisc(Tables& tables) {
214 214
215} // Anonymous namespace 215} // Anonymous namespace
216 216
217StateTracker::StateTracker(Core::System& system) : system{system} {} 217StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags} {
218 218 auto& dirty = gpu.Maxwell3D().dirty;
219void StateTracker::Initialize() {
220 auto& dirty = system.GPU().Maxwell3D().dirty;
221 auto& tables = dirty.tables; 219 auto& tables = dirty.tables;
222 SetupDirtyRenderTargets(tables); 220 SetupDirtyRenderTargets(tables);
223 SetupDirtyColorMasks(tables); 221 SetupDirtyColorMasks(tables);
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h
index 0f823288e..9d127548f 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.h
+++ b/src/video_core/renderer_opengl/gl_state_tracker.h
@@ -13,8 +13,8 @@
13#include "video_core/dirty_flags.h" 13#include "video_core/dirty_flags.h"
14#include "video_core/engines/maxwell_3d.h" 14#include "video_core/engines/maxwell_3d.h"
15 15
16namespace Core { 16namespace Tegra {
17class System; 17class GPU;
18} 18}
19 19
20namespace OpenGL { 20namespace OpenGL {
@@ -90,9 +90,7 @@ static_assert(Last <= std::numeric_limits<u8>::max());
90 90
91class StateTracker { 91class StateTracker {
92public: 92public:
93 explicit StateTracker(Core::System& system); 93 explicit StateTracker(Tegra::GPU& gpu);
94
95 void Initialize();
96 94
97 void BindIndexBuffer(GLuint new_index_buffer) { 95 void BindIndexBuffer(GLuint new_index_buffer) {
98 if (index_buffer == new_index_buffer) { 96 if (index_buffer == new_index_buffer) {
@@ -103,7 +101,6 @@ public:
103 } 101 }
104 102
105 void NotifyScreenDrawVertexArray() { 103 void NotifyScreenDrawVertexArray() {
106 auto& flags = system.GPU().Maxwell3D().dirty.flags;
107 flags[OpenGL::Dirty::VertexFormats] = true; 104 flags[OpenGL::Dirty::VertexFormats] = true;
108 flags[OpenGL::Dirty::VertexFormat0 + 0] = true; 105 flags[OpenGL::Dirty::VertexFormat0 + 0] = true;
109 flags[OpenGL::Dirty::VertexFormat0 + 1] = true; 106 flags[OpenGL::Dirty::VertexFormat0 + 1] = true;
@@ -117,98 +114,81 @@ public:
117 } 114 }
118 115
119 void NotifyPolygonModes() { 116 void NotifyPolygonModes() {
120 auto& flags = system.GPU().Maxwell3D().dirty.flags;
121 flags[OpenGL::Dirty::PolygonModes] = true; 117 flags[OpenGL::Dirty::PolygonModes] = true;
122 flags[OpenGL::Dirty::PolygonModeFront] = true; 118 flags[OpenGL::Dirty::PolygonModeFront] = true;
123 flags[OpenGL::Dirty::PolygonModeBack] = true; 119 flags[OpenGL::Dirty::PolygonModeBack] = true;
124 } 120 }
125 121
126 void NotifyViewport0() { 122 void NotifyViewport0() {
127 auto& flags = system.GPU().Maxwell3D().dirty.flags;
128 flags[OpenGL::Dirty::Viewports] = true; 123 flags[OpenGL::Dirty::Viewports] = true;
129 flags[OpenGL::Dirty::Viewport0] = true; 124 flags[OpenGL::Dirty::Viewport0] = true;
130 } 125 }
131 126
132 void NotifyScissor0() { 127 void NotifyScissor0() {
133 auto& flags = system.GPU().Maxwell3D().dirty.flags;
134 flags[OpenGL::Dirty::Scissors] = true; 128 flags[OpenGL::Dirty::Scissors] = true;
135 flags[OpenGL::Dirty::Scissor0] = true; 129 flags[OpenGL::Dirty::Scissor0] = true;
136 } 130 }
137 131
138 void NotifyColorMask0() { 132 void NotifyColorMask0() {
139 auto& flags = system.GPU().Maxwell3D().dirty.flags;
140 flags[OpenGL::Dirty::ColorMasks] = true; 133 flags[OpenGL::Dirty::ColorMasks] = true;
141 flags[OpenGL::Dirty::ColorMask0] = true; 134 flags[OpenGL::Dirty::ColorMask0] = true;
142 } 135 }
143 136
144 void NotifyBlend0() { 137 void NotifyBlend0() {
145 auto& flags = system.GPU().Maxwell3D().dirty.flags;
146 flags[OpenGL::Dirty::BlendStates] = true; 138 flags[OpenGL::Dirty::BlendStates] = true;
147 flags[OpenGL::Dirty::BlendState0] = true; 139 flags[OpenGL::Dirty::BlendState0] = true;
148 } 140 }
149 141
150 void NotifyFramebuffer() { 142 void NotifyFramebuffer() {
151 auto& flags = system.GPU().Maxwell3D().dirty.flags;
152 flags[VideoCommon::Dirty::RenderTargets] = true; 143 flags[VideoCommon::Dirty::RenderTargets] = true;
153 } 144 }
154 145
155 void NotifyFrontFace() { 146 void NotifyFrontFace() {
156 auto& flags = system.GPU().Maxwell3D().dirty.flags;
157 flags[OpenGL::Dirty::FrontFace] = true; 147 flags[OpenGL::Dirty::FrontFace] = true;
158 } 148 }
159 149
160 void NotifyCullTest() { 150 void NotifyCullTest() {
161 auto& flags = system.GPU().Maxwell3D().dirty.flags;
162 flags[OpenGL::Dirty::CullTest] = true; 151 flags[OpenGL::Dirty::CullTest] = true;
163 } 152 }
164 153
165 void NotifyDepthMask() { 154 void NotifyDepthMask() {
166 auto& flags = system.GPU().Maxwell3D().dirty.flags;
167 flags[OpenGL::Dirty::DepthMask] = true; 155 flags[OpenGL::Dirty::DepthMask] = true;
168 } 156 }
169 157
170 void NotifyDepthTest() { 158 void NotifyDepthTest() {
171 auto& flags = system.GPU().Maxwell3D().dirty.flags;
172 flags[OpenGL::Dirty::DepthTest] = true; 159 flags[OpenGL::Dirty::DepthTest] = true;
173 } 160 }
174 161
175 void NotifyStencilTest() { 162 void NotifyStencilTest() {
176 auto& flags = system.GPU().Maxwell3D().dirty.flags;
177 flags[OpenGL::Dirty::StencilTest] = true; 163 flags[OpenGL::Dirty::StencilTest] = true;
178 } 164 }
179 165
180 void NotifyPolygonOffset() { 166 void NotifyPolygonOffset() {
181 auto& flags = system.GPU().Maxwell3D().dirty.flags;
182 flags[OpenGL::Dirty::PolygonOffset] = true; 167 flags[OpenGL::Dirty::PolygonOffset] = true;
183 } 168 }
184 169
185 void NotifyRasterizeEnable() { 170 void NotifyRasterizeEnable() {
186 auto& flags = system.GPU().Maxwell3D().dirty.flags;
187 flags[OpenGL::Dirty::RasterizeEnable] = true; 171 flags[OpenGL::Dirty::RasterizeEnable] = true;
188 } 172 }
189 173
190 void NotifyFramebufferSRGB() { 174 void NotifyFramebufferSRGB() {
191 auto& flags = system.GPU().Maxwell3D().dirty.flags;
192 flags[OpenGL::Dirty::FramebufferSRGB] = true; 175 flags[OpenGL::Dirty::FramebufferSRGB] = true;
193 } 176 }
194 177
195 void NotifyLogicOp() { 178 void NotifyLogicOp() {
196 auto& flags = system.GPU().Maxwell3D().dirty.flags;
197 flags[OpenGL::Dirty::LogicOp] = true; 179 flags[OpenGL::Dirty::LogicOp] = true;
198 } 180 }
199 181
200 void NotifyClipControl() { 182 void NotifyClipControl() {
201 auto& flags = system.GPU().Maxwell3D().dirty.flags;
202 flags[OpenGL::Dirty::ClipControl] = true; 183 flags[OpenGL::Dirty::ClipControl] = true;
203 } 184 }
204 185
205 void NotifyAlphaTest() { 186 void NotifyAlphaTest() {
206 auto& flags = system.GPU().Maxwell3D().dirty.flags;
207 flags[OpenGL::Dirty::AlphaTest] = true; 187 flags[OpenGL::Dirty::AlphaTest] = true;
208 } 188 }
209 189
210private: 190private:
211 Core::System& system; 191 Tegra::Engines::Maxwell3D::DirtyState::Flags& flags;
212 192
213 GLuint index_buffer = 0; 193 GLuint index_buffer = 0;
214}; 194};
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index f403f388a..a863ef218 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -532,10 +532,12 @@ OGLTextureView CachedSurfaceView::CreateTextureView() const {
532 return texture_view; 532 return texture_view;
533} 533}
534 534
535TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system, 535TextureCacheOpenGL::TextureCacheOpenGL(VideoCore::RasterizerInterface& rasterizer,
536 VideoCore::RasterizerInterface& rasterizer, 536 Tegra::Engines::Maxwell3D& maxwell3d,
537 const Device& device, StateTracker& state_tracker) 537 Tegra::MemoryManager& gpu_memory, const Device& device,
538 : TextureCacheBase{system, rasterizer, device.HasASTC()}, state_tracker{state_tracker} { 538 StateTracker& state_tracker_)
539 : TextureCacheBase{rasterizer, maxwell3d, gpu_memory, device.HasASTC()}, state_tracker{
540 state_tracker_} {
539 src_framebuffer.Create(); 541 src_framebuffer.Create();
540 dst_framebuffer.Create(); 542 dst_framebuffer.Create();
541} 543}
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index de8f18489..7787134fc 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -129,8 +129,10 @@ private:
129 129
130class TextureCacheOpenGL final : public TextureCacheBase { 130class TextureCacheOpenGL final : public TextureCacheBase {
131public: 131public:
132 explicit TextureCacheOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 132 explicit TextureCacheOpenGL(VideoCore::RasterizerInterface& rasterizer,
133 const Device& device, StateTracker& state_tracker); 133 Tegra::Engines::Maxwell3D& maxwell3d,
134 Tegra::MemoryManager& gpu_memory, const Device& device,
135 StateTracker& state_tracker);
134 ~TextureCacheOpenGL(); 136 ~TextureCacheOpenGL();
135 137
136protected: 138protected:
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index b759c2dba..a4c5b8f74 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -275,11 +275,13 @@ public:
275 } 275 }
276}; 276};
277 277
278RendererOpenGL::RendererOpenGL(Core::System& system_, Core::Frontend::EmuWindow& emu_window_, 278RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
279 Tegra::GPU& gpu_, 279 Core::Frontend::EmuWindow& emu_window_,
280 std::unique_ptr<Core::Frontend::GraphicsContext> context_) 280 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
281 : RendererBase{emu_window_, std::move(context_)}, system{system_}, 281 std::unique_ptr<Core::Frontend::GraphicsContext> context)
282 emu_window{emu_window_}, gpu{gpu_}, program_manager{device}, has_debug_tool{HasDebugTool()} {} 282 : RendererBase{emu_window_, std::move(context)}, telemetry_session{telemetry_session_},
283 emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, program_manager{device},
284 has_debug_tool{HasDebugTool()} {}
283 285
284RendererOpenGL::~RendererOpenGL() = default; 286RendererOpenGL::~RendererOpenGL() = default;
285 287
@@ -386,7 +388,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
386 VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)}; 388 VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)};
387 const u32 bytes_per_pixel{VideoCore::Surface::GetBytesPerPixel(pixel_format)}; 389 const u32 bytes_per_pixel{VideoCore::Surface::GetBytesPerPixel(pixel_format)};
388 const u64 size_in_bytes{framebuffer.stride * framebuffer.height * bytes_per_pixel}; 390 const u64 size_in_bytes{framebuffer.stride * framebuffer.height * bytes_per_pixel};
389 u8* const host_ptr{system.Memory().GetPointer(framebuffer_addr)}; 391 u8* const host_ptr{cpu_memory.GetPointer(framebuffer_addr)};
390 rasterizer->FlushRegion(ToCacheAddr(host_ptr), size_in_bytes); 392 rasterizer->FlushRegion(ToCacheAddr(host_ptr), size_in_bytes);
391 393
392 // TODO(Rodrigo): Read this from HLE 394 // TODO(Rodrigo): Read this from HLE
@@ -471,7 +473,6 @@ void RendererOpenGL::AddTelemetryFields() {
471 LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); 473 LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor);
472 LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); 474 LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model);
473 475
474 auto& telemetry_session = system.TelemetrySession();
475 constexpr auto user_system = Common::Telemetry::FieldType::UserSystem; 476 constexpr auto user_system = Common::Telemetry::FieldType::UserSystem;
476 telemetry_session.AddField(user_system, "GPU_Vendor", gpu_vendor); 477 telemetry_session.AddField(user_system, "GPU_Vendor", gpu_vendor);
477 telemetry_session.AddField(user_system, "GPU_Model", gpu_model); 478 telemetry_session.AddField(user_system, "GPU_Model", gpu_model);
@@ -482,8 +483,8 @@ void RendererOpenGL::CreateRasterizer() {
482 if (rasterizer) { 483 if (rasterizer) {
483 return; 484 return;
484 } 485 }
485 rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, device, screen_info, 486 rasterizer = std::make_unique<RasterizerOpenGL>(emu_window, gpu, cpu_memory, device,
486 program_manager, state_tracker); 487 screen_info, program_manager, state_tracker);
487} 488}
488 489
489void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, 490void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 52ea76b7d..5329577fb 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -16,16 +16,25 @@
16 16
17namespace Core { 17namespace Core {
18class System; 18class System;
19} 19class TelemetrySession;
20} // namespace Core
20 21
21namespace Core::Frontend { 22namespace Core::Frontend {
22class EmuWindow; 23class EmuWindow;
23} 24}
24 25
26namespace Core::Memory {
27class Memory;
28}
29
25namespace Layout { 30namespace Layout {
26struct FramebufferLayout; 31struct FramebufferLayout;
27} 32}
28 33
34namespace Tegra {
35class GPU;
36}
37
29namespace OpenGL { 38namespace OpenGL {
30 39
31/// Structure used for storing information about the textures for the Switch screen 40/// Structure used for storing information about the textures for the Switch screen
@@ -56,7 +65,8 @@ class FrameMailbox;
56 65
57class RendererOpenGL final : public VideoCore::RendererBase { 66class RendererOpenGL final : public VideoCore::RendererBase {
58public: 67public:
59 explicit RendererOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, 68 explicit RendererOpenGL(Core::TelemetrySession& telemetry_session,
69 Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory,
60 Tegra::GPU& gpu, 70 Tegra::GPU& gpu,
61 std::unique_ptr<Core::Frontend::GraphicsContext> context); 71 std::unique_ptr<Core::Frontend::GraphicsContext> context);
62 ~RendererOpenGL() override; 72 ~RendererOpenGL() override;
@@ -94,12 +104,13 @@ private:
94 104
95 bool Present(int timeout_ms); 105 bool Present(int timeout_ms);
96 106
97 Core::System& system; 107 Core::TelemetrySession& telemetry_session;
98 Core::Frontend::EmuWindow& emu_window; 108 Core::Frontend::EmuWindow& emu_window;
109 Core::Memory::Memory& cpu_memory;
99 Tegra::GPU& gpu; 110 Tegra::GPU& gpu;
100 const Device device;
101 111
102 StateTracker state_tracker{system}; 112 const Device device;
113 StateTracker state_tracker{gpu};
103 114
104 // OpenGL object IDs 115 // OpenGL object IDs
105 OGLBuffer vertex_buffer; 116 OGLBuffer vertex_buffer;
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index ae46e0444..0e4583986 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -86,7 +86,7 @@ Common::DynamicLibrary OpenVulkanLibrary() {
86 if (!library.Open(filename.c_str())) { 86 if (!library.Open(filename.c_str())) {
87 // Android devices may not have libvulkan.so.1, only libvulkan.so. 87 // Android devices may not have libvulkan.so.1, only libvulkan.so.
88 filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); 88 filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
89 library.Open(filename.c_str()); 89 (void)library.Open(filename.c_str());
90 } 90 }
91#endif 91#endif
92 return library; 92 return library;
@@ -237,10 +237,12 @@ std::string BuildCommaSeparatedExtensions(std::vector<std::string> available_ext
237 237
238} // Anonymous namespace 238} // Anonymous namespace
239 239
240RendererVulkan::RendererVulkan(Core::System& system_, Core::Frontend::EmuWindow& emu_window, 240RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
241 Tegra::GPU& gpu_, 241 Core::Frontend::EmuWindow& emu_window,
242 Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
242 std::unique_ptr<Core::Frontend::GraphicsContext> context) 243 std::unique_ptr<Core::Frontend::GraphicsContext> context)
243 : RendererBase{emu_window, std::move(context)}, system{system_}, gpu{gpu_} {} 244 : RendererBase{emu_window, std::move(context)}, telemetry_session{telemetry_session_},
245 cpu_memory{cpu_memory_}, gpu{gpu_} {}
244 246
245RendererVulkan::~RendererVulkan() { 247RendererVulkan::~RendererVulkan() {
246 ShutDown(); 248 ShutDown();
@@ -304,15 +306,15 @@ bool RendererVulkan::Init() {
304 swapchain = std::make_unique<VKSwapchain>(*surface, *device); 306 swapchain = std::make_unique<VKSwapchain>(*surface, *device);
305 swapchain->Create(framebuffer.width, framebuffer.height, false); 307 swapchain->Create(framebuffer.width, framebuffer.height, false);
306 308
307 state_tracker = std::make_unique<StateTracker>(system); 309 state_tracker = std::make_unique<StateTracker>(gpu);
308 310
309 scheduler = std::make_unique<VKScheduler>(*device, *resource_manager, *state_tracker); 311 scheduler = std::make_unique<VKScheduler>(*device, *resource_manager, *state_tracker);
310 312
311 rasterizer = std::make_unique<RasterizerVulkan>(system, render_window, screen_info, *device, 313 rasterizer = std::make_unique<RasterizerVulkan>(
312 *resource_manager, *memory_manager, 314 render_window, gpu, gpu.MemoryManager(), cpu_memory, screen_info, *device,
313 *state_tracker, *scheduler); 315 *resource_manager, *memory_manager, *state_tracker, *scheduler);
314 316
315 blit_screen = std::make_unique<VKBlitScreen>(system, render_window, *rasterizer, *device, 317 blit_screen = std::make_unique<VKBlitScreen>(cpu_memory, render_window, *rasterizer, *device,
316 *resource_manager, *memory_manager, *swapchain, 318 *resource_manager, *memory_manager, *swapchain,
317 *scheduler, screen_info); 319 *scheduler, screen_info);
318 320
@@ -440,8 +442,7 @@ void RendererVulkan::Report() const {
440 LOG_INFO(Render_Vulkan, "Device: {}", model_name); 442 LOG_INFO(Render_Vulkan, "Device: {}", model_name);
441 LOG_INFO(Render_Vulkan, "Vulkan: {}", api_version); 443 LOG_INFO(Render_Vulkan, "Vulkan: {}", api_version);
442 444
443 auto& telemetry_session = system.TelemetrySession(); 445 static constexpr auto field = Common::Telemetry::FieldType::UserSystem;
444 constexpr auto field = Common::Telemetry::FieldType::UserSystem;
445 telemetry_session.AddField(field, "GPU_Vendor", vendor_name); 446 telemetry_session.AddField(field, "GPU_Vendor", vendor_name);
446 telemetry_session.AddField(field, "GPU_Model", model_name); 447 telemetry_session.AddField(field, "GPU_Model", model_name);
447 telemetry_session.AddField(field, "GPU_Vulkan_Driver", driver_name); 448 telemetry_session.AddField(field, "GPU_Vulkan_Driver", driver_name);
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h
index 13debbbc0..ddff77942 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.h
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.h
@@ -14,7 +14,15 @@
14#include "video_core/renderer_vulkan/wrapper.h" 14#include "video_core/renderer_vulkan/wrapper.h"
15 15
16namespace Core { 16namespace Core {
17class System; 17class TelemetrySession;
18}
19
20namespace Core::Memory {
21class Memory;
22}
23
24namespace Tegra {
25class GPU;
18} 26}
19 27
20namespace Vulkan { 28namespace Vulkan {
@@ -38,7 +46,8 @@ struct VKScreenInfo {
38 46
39class RendererVulkan final : public VideoCore::RendererBase { 47class RendererVulkan final : public VideoCore::RendererBase {
40public: 48public:
41 explicit RendererVulkan(Core::System& system, Core::Frontend::EmuWindow& emu_window, 49 explicit RendererVulkan(Core::TelemetrySession& telemtry_session,
50 Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory,
42 Tegra::GPU& gpu, 51 Tegra::GPU& gpu,
43 std::unique_ptr<Core::Frontend::GraphicsContext> context); 52 std::unique_ptr<Core::Frontend::GraphicsContext> context);
44 ~RendererVulkan() override; 53 ~RendererVulkan() override;
@@ -59,7 +68,8 @@ private:
59 68
60 void Report() const; 69 void Report() const;
61 70
62 Core::System& system; 71 Core::TelemetrySession& telemetry_session;
72 Core::Memory::Memory& cpu_memory;
63 Tegra::GPU& gpu; 73 Tegra::GPU& gpu;
64 74
65 Common::DynamicLibrary library; 75 Common::DynamicLibrary library;
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index a551e3de8..2bea7b24d 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -210,14 +210,16 @@ struct VKBlitScreen::BufferData {
210 // Unaligned image data goes here 210 // Unaligned image data goes here
211}; 211};
212 212
213VKBlitScreen::VKBlitScreen(Core::System& system, Core::Frontend::EmuWindow& render_window, 213VKBlitScreen::VKBlitScreen(Core::Memory::Memory& cpu_memory_,
214 VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, 214 Core::Frontend::EmuWindow& render_window_,
215 VKResourceManager& resource_manager, VKMemoryManager& memory_manager, 215 VideoCore::RasterizerInterface& rasterizer_, const VKDevice& device_,
216 VKSwapchain& swapchain, VKScheduler& scheduler, 216 VKResourceManager& resource_manager_, VKMemoryManager& memory_manager_,
217 const VKScreenInfo& screen_info) 217 VKSwapchain& swapchain_, VKScheduler& scheduler_,
218 : system{system}, render_window{render_window}, rasterizer{rasterizer}, device{device}, 218 const VKScreenInfo& screen_info_)
219 resource_manager{resource_manager}, memory_manager{memory_manager}, swapchain{swapchain}, 219 : cpu_memory{cpu_memory_}, render_window{render_window_},
220 scheduler{scheduler}, image_count{swapchain.GetImageCount()}, screen_info{screen_info} { 220 rasterizer{rasterizer_}, device{device_}, resource_manager{resource_manager_},
221 memory_manager{memory_manager_}, swapchain{swapchain_}, scheduler{scheduler_},
222 image_count{swapchain.GetImageCount()}, screen_info{screen_info_} {
221 watches.resize(image_count); 223 watches.resize(image_count);
222 std::generate(watches.begin(), watches.end(), 224 std::generate(watches.begin(), watches.end(),
223 []() { return std::make_unique<VKFenceWatch>(); }); 225 []() { return std::make_unique<VKFenceWatch>(); });
@@ -259,7 +261,7 @@ std::tuple<VKFence&, VkSemaphore> VKBlitScreen::Draw(const Tegra::FramebufferCon
259 const auto pixel_format = 261 const auto pixel_format =
260 VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format); 262 VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format);
261 const VAddr framebuffer_addr = framebuffer.address + framebuffer.offset; 263 const VAddr framebuffer_addr = framebuffer.address + framebuffer.offset;
262 const auto host_ptr = system.Memory().GetPointer(framebuffer_addr); 264 const auto host_ptr = cpu_memory.GetPointer(framebuffer_addr);
263 rasterizer.FlushRegion(ToCacheAddr(host_ptr), GetSizeInBytes(framebuffer)); 265 rasterizer.FlushRegion(ToCacheAddr(host_ptr), GetSizeInBytes(framebuffer));
264 266
265 // TODO(Rodrigo): Read this from HLE 267 // TODO(Rodrigo): Read this from HLE
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h
index 243640fab..838d38f69 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.h
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.h
@@ -15,6 +15,10 @@ namespace Core {
15class System; 15class System;
16} 16}
17 17
18namespace Core::Memory {
19class Memory;
20}
21
18namespace Core::Frontend { 22namespace Core::Frontend {
19class EmuWindow; 23class EmuWindow;
20} 24}
@@ -39,7 +43,8 @@ class VKSwapchain;
39 43
40class VKBlitScreen final { 44class VKBlitScreen final {
41public: 45public:
42 explicit VKBlitScreen(Core::System& system, Core::Frontend::EmuWindow& render_window, 46 explicit VKBlitScreen(Core::Memory::Memory& cpu_memory,
47 Core::Frontend::EmuWindow& render_window,
43 VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, 48 VideoCore::RasterizerInterface& rasterizer, const VKDevice& device,
44 VKResourceManager& resource_manager, VKMemoryManager& memory_manager, 49 VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
45 VKSwapchain& swapchain, VKScheduler& scheduler, 50 VKSwapchain& swapchain, VKScheduler& scheduler,
@@ -81,7 +86,7 @@ private:
81 u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, 86 u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer,
82 std::size_t image_index) const; 87 std::size_t image_index) const;
83 88
84 Core::System& system; 89 Core::Memory::Memory& cpu_memory;
85 Core::Frontend::EmuWindow& render_window; 90 Core::Frontend::EmuWindow& render_window;
86 VideoCore::RasterizerInterface& rasterizer; 91 VideoCore::RasterizerInterface& rasterizer;
87 const VKDevice& device; 92 const VKDevice& device;
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 1d2f8b557..d9d3da9ea 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -145,14 +145,15 @@ void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst
145 }); 145 });
146} 146}
147 147
148VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, 148VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer,
149 const VKDevice& device, VKMemoryManager& memory_manager, 149 Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
150 VKScheduler& scheduler, VKStagingBufferPool& staging_pool) 150 const VKDevice& device_, VKMemoryManager& memory_manager_,
151 : VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, system, 151 VKScheduler& scheduler_, VKStagingBufferPool& staging_pool_)
152 CreateStreamBuffer(device, 152 : VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, gpu_memory, cpu_memory,
153 scheduler)}, 153 CreateStreamBuffer(device_,
154 device{device}, memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{ 154 scheduler_)},
155 staging_pool} {} 155 device{device_}, memory_manager{memory_manager_}, scheduler{scheduler_}, staging_pool{
156 staging_pool_} {}
156 157
157VKBufferCache::~VKBufferCache() = default; 158VKBufferCache::~VKBufferCache() = default;
158 159
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index 991ee451c..7fb5ceedf 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -13,10 +13,6 @@
13#include "video_core/renderer_vulkan/vk_stream_buffer.h" 13#include "video_core/renderer_vulkan/vk_stream_buffer.h"
14#include "video_core/renderer_vulkan/wrapper.h" 14#include "video_core/renderer_vulkan/wrapper.h"
15 15
16namespace Core {
17class System;
18}
19
20namespace Vulkan { 16namespace Vulkan {
21 17
22class VKDevice; 18class VKDevice;
@@ -53,7 +49,8 @@ private:
53 49
54class VKBufferCache final : public VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer> { 50class VKBufferCache final : public VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer> {
55public: 51public:
56 explicit VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, 52 explicit VKBufferCache(VideoCore::RasterizerInterface& rasterizer,
53 Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
57 const VKDevice& device, VKMemoryManager& memory_manager, 54 const VKDevice& device, VKMemoryManager& memory_manager,
58 VKScheduler& scheduler, VKStagingBufferPool& staging_pool); 55 VKScheduler& scheduler, VKStagingBufferPool& staging_pool);
59 ~VKBufferCache(); 56 ~VKBufferCache();
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp
index d7f65d435..55a8348fc 100644
--- a/src/video_core/renderer_vulkan/vk_fence_manager.cpp
+++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp
@@ -71,12 +71,12 @@ bool InnerFence::IsEventSignalled() const {
71 } 71 }
72} 72}
73 73
74VKFenceManager::VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 74VKFenceManager::VKFenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
75 const VKDevice& device, VKScheduler& scheduler, 75 Tegra::MemoryManager& memory_manager, VKTextureCache& texture_cache,
76 VKTextureCache& texture_cache, VKBufferCache& buffer_cache, 76 VKBufferCache& buffer_cache, VKQueryCache& query_cache,
77 VKQueryCache& query_cache) 77 const VKDevice& device_, VKScheduler& scheduler_)
78 : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache, query_cache), 78 : GenericFenceManager(rasterizer, gpu, texture_cache, buffer_cache, query_cache),
79 device{device}, scheduler{scheduler} {} 79 device{device_}, scheduler{scheduler_} {}
80 80
81Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) { 81Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) {
82 return std::make_shared<InnerFence>(device, scheduler, value, is_stubbed); 82 return std::make_shared<InnerFence>(device, scheduler, value, is_stubbed);
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.h b/src/video_core/renderer_vulkan/vk_fence_manager.h
index 043fe7947..1547d6d30 100644
--- a/src/video_core/renderer_vulkan/vk_fence_manager.h
+++ b/src/video_core/renderer_vulkan/vk_fence_manager.h
@@ -55,10 +55,10 @@ using GenericFenceManager =
55 55
56class VKFenceManager final : public GenericFenceManager { 56class VKFenceManager final : public GenericFenceManager {
57public: 57public:
58 explicit VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 58 explicit VKFenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu,
59 const VKDevice& device, VKScheduler& scheduler, 59 Tegra::MemoryManager& memory_manager, VKTextureCache& texture_cache,
60 VKTextureCache& texture_cache, VKBufferCache& buffer_cache, 60 VKBufferCache& buffer_cache, VKQueryCache& query_cache,
61 VKQueryCache& query_cache); 61 const VKDevice& device, VKScheduler& scheduler);
62 62
63protected: 63protected:
64 Fence CreateFence(u32 value, bool is_stubbed) override; 64 Fence CreateFence(u32 value, bool is_stubbed) override;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index cfdcdd6ab..5c038f4bc 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -135,64 +135,56 @@ bool ComputePipelineCacheKey::operator==(const ComputePipelineCacheKey& rhs) con
135 return std::memcmp(&rhs, this, sizeof *this) == 0; 135 return std::memcmp(&rhs, this, sizeof *this) == 0;
136} 136}
137 137
138Shader::Shader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, 138Shader::Shader(Tegra::Engines::ConstBufferEngineInterface& engine, Tegra::Engines::ShaderType stage,
139 VideoCommon::Shader::ProgramCode program_code, u32 main_offset) 139 GPUVAddr gpu_addr_, VAddr cpu_addr, VideoCommon::Shader::ProgramCode program_code_,
140 : gpu_addr{gpu_addr}, program_code{std::move(program_code)}, 140 u32 main_offset)
141 registry{stage, GetEngine(system, stage)}, shader_ir{this->program_code, main_offset, 141 : gpu_addr(gpu_addr_), program_code(std::move(program_code_)), registry(stage, engine),
142 compiler_settings, registry}, 142 shader_ir(program_code, main_offset, compiler_settings, registry),
143 entries{GenerateShaderEntries(shader_ir)} {} 143 entries(GenerateShaderEntries(shader_ir)) {}
144 144
145Shader::~Shader() = default; 145Shader::~Shader() = default;
146 146
147Tegra::Engines::ConstBufferEngineInterface& Shader::GetEngine(Core::System& system, 147VKPipelineCache::VKPipelineCache(RasterizerVulkan& rasterizer, Tegra::GPU& gpu_,
148 Tegra::Engines::ShaderType stage) { 148 Tegra::Engines::Maxwell3D& maxwell3d_,
149 if (stage == ShaderType::Compute) { 149 Tegra::Engines::KeplerCompute& kepler_compute_,
150 return system.GPU().KeplerCompute(); 150 Tegra::MemoryManager& gpu_memory_, const VKDevice& device_,
151 } else { 151 VKScheduler& scheduler_, VKDescriptorPool& descriptor_pool_,
152 return system.GPU().Maxwell3D(); 152 VKUpdateDescriptorQueue& update_descriptor_queue_,
153 } 153 VKRenderPassCache& renderpass_cache_)
154} 154 : VideoCommon::ShaderCache<Shader>{rasterizer}, gpu{gpu_}, maxwell3d{maxwell3d_},
155 155 kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_}, device{device_},
156VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, 156 scheduler{scheduler_}, descriptor_pool{descriptor_pool_},
157 const VKDevice& device, VKScheduler& scheduler, 157 update_descriptor_queue{update_descriptor_queue_}, renderpass_cache{renderpass_cache_} {}
158 VKDescriptorPool& descriptor_pool,
159 VKUpdateDescriptorQueue& update_descriptor_queue,
160 VKRenderPassCache& renderpass_cache)
161 : VideoCommon::ShaderCache<Shader>{rasterizer}, system{system}, device{device},
162 scheduler{scheduler}, descriptor_pool{descriptor_pool},
163 update_descriptor_queue{update_descriptor_queue}, renderpass_cache{renderpass_cache} {}
164 158
165VKPipelineCache::~VKPipelineCache() = default; 159VKPipelineCache::~VKPipelineCache() = default;
166 160
167std::array<Shader*, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { 161std::array<Shader*, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() {
168 const auto& gpu = system.GPU().Maxwell3D();
169
170 std::array<Shader*, Maxwell::MaxShaderProgram> shaders{}; 162 std::array<Shader*, Maxwell::MaxShaderProgram> shaders{};
163
171 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 164 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
172 const auto program{static_cast<Maxwell::ShaderProgram>(index)}; 165 const auto program{static_cast<Maxwell::ShaderProgram>(index)};
173 166
174 // Skip stages that are not enabled 167 // Skip stages that are not enabled
175 if (!gpu.regs.IsShaderConfigEnabled(index)) { 168 if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
176 continue; 169 continue;
177 } 170 }
178 171
179 auto& memory_manager{system.GPU().MemoryManager()}; 172 const GPUVAddr gpu_addr{GetShaderAddress(maxwell3d, program)};
180 const GPUVAddr program_addr{GetShaderAddress(system, program)}; 173 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
181 const std::optional cpu_addr = memory_manager.GpuToCpuAddress(program_addr);
182 ASSERT(cpu_addr); 174 ASSERT(cpu_addr);
183 175
184 Shader* result = cpu_addr ? TryGet(*cpu_addr) : null_shader.get(); 176 Shader* result = cpu_addr ? TryGet(*cpu_addr) : null_shader.get();
185 if (!result) { 177 if (!result) {
186 const auto host_ptr{memory_manager.GetPointer(program_addr)}; 178 const u8* const host_ptr{gpu_memory.GetPointer(gpu_addr)};
187 179
188 // No shader found - create a new one 180 // No shader found - create a new one
189 constexpr u32 stage_offset = STAGE_MAIN_OFFSET; 181 static constexpr u32 stage_offset = STAGE_MAIN_OFFSET;
190 const auto stage = static_cast<ShaderType>(index == 0 ? 0 : index - 1); 182 const auto stage = static_cast<ShaderType>(index == 0 ? 0 : index - 1);
191 ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, false); 183 ProgramCode code = GetShaderCode(gpu_memory, gpu_addr, host_ptr, false);
192 const std::size_t size_in_bytes = code.size() * sizeof(u64); 184 const std::size_t size_in_bytes = code.size() * sizeof(u64);
193 185
194 auto shader = std::make_unique<Shader>(system, stage, program_addr, std::move(code), 186 auto shader = std::make_unique<Shader>(maxwell3d, stage, gpu_addr, *cpu_addr,
195 stage_offset); 187 std::move(code), stage_offset);
196 result = shader.get(); 188 result = shader.get();
197 189
198 if (cpu_addr) { 190 if (cpu_addr) {
@@ -215,11 +207,11 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline(
215 } 207 }
216 last_graphics_key = key; 208 last_graphics_key = key;
217 209
218 if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(system.GPU())) { 210 if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(gpu)) {
219 std::unique_lock lock{pipeline_cache}; 211 std::unique_lock lock{pipeline_cache};
220 const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); 212 const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key);
221 if (is_cache_miss) { 213 if (is_cache_miss) {
222 system.GPU().ShaderNotify().MarkSharderBuilding(); 214 gpu.ShaderNotify().MarkSharderBuilding();
223 LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); 215 LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash());
224 const auto [program, bindings] = DecompileShaders(key.fixed_state); 216 const auto [program, bindings] = DecompileShaders(key.fixed_state);
225 async_shaders.QueueVulkanShader(this, device, scheduler, descriptor_pool, 217 async_shaders.QueueVulkanShader(this, device, scheduler, descriptor_pool,
@@ -233,13 +225,13 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline(
233 const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); 225 const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key);
234 auto& entry = pair->second; 226 auto& entry = pair->second;
235 if (is_cache_miss) { 227 if (is_cache_miss) {
236 system.GPU().ShaderNotify().MarkSharderBuilding(); 228 gpu.ShaderNotify().MarkSharderBuilding();
237 LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); 229 LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash());
238 const auto [program, bindings] = DecompileShaders(key.fixed_state); 230 const auto [program, bindings] = DecompileShaders(key.fixed_state);
239 entry = std::make_unique<VKGraphicsPipeline>(device, scheduler, descriptor_pool, 231 entry = std::make_unique<VKGraphicsPipeline>(device, scheduler, descriptor_pool,
240 update_descriptor_queue, renderpass_cache, key, 232 update_descriptor_queue, renderpass_cache, key,
241 bindings, program); 233 bindings, program);
242 system.GPU().ShaderNotify().MarkShaderComplete(); 234 gpu.ShaderNotify().MarkShaderComplete();
243 } 235 }
244 last_graphics_pipeline = entry.get(); 236 last_graphics_pipeline = entry.get();
245 return last_graphics_pipeline; 237 return last_graphics_pipeline;
@@ -255,22 +247,21 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
255 } 247 }
256 LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); 248 LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash());
257 249
258 auto& memory_manager = system.GPU().MemoryManager(); 250 const GPUVAddr gpu_addr = key.shader;
259 const auto program_addr = key.shader;
260 251
261 const auto cpu_addr = memory_manager.GpuToCpuAddress(program_addr); 252 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
262 ASSERT(cpu_addr); 253 ASSERT(cpu_addr);
263 254
264 Shader* shader = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get(); 255 Shader* shader = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get();
265 if (!shader) { 256 if (!shader) {
266 // No shader found - create a new one 257 // No shader found - create a new one
267 const auto host_ptr = memory_manager.GetPointer(program_addr); 258 const auto host_ptr = gpu_memory.GetPointer(gpu_addr);
268 259
269 ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, true); 260 ProgramCode code = GetShaderCode(gpu_memory, gpu_addr, host_ptr, true);
270 const std::size_t size_in_bytes = code.size() * sizeof(u64); 261 const std::size_t size_in_bytes = code.size() * sizeof(u64);
271 262
272 auto shader_info = std::make_unique<Shader>(system, ShaderType::Compute, program_addr, 263 auto shader_info = std::make_unique<Shader>(kepler_compute, ShaderType::Compute, gpu_addr,
273 std::move(code), KERNEL_MAIN_OFFSET); 264 *cpu_addr, std::move(code), KERNEL_MAIN_OFFSET);
274 shader = shader_info.get(); 265 shader = shader_info.get();
275 266
276 if (cpu_addr) { 267 if (cpu_addr) {
@@ -298,7 +289,7 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach
298} 289}
299 290
300void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) { 291void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) {
301 system.GPU().ShaderNotify().MarkShaderComplete(); 292 gpu.ShaderNotify().MarkShaderComplete();
302 std::unique_lock lock{pipeline_cache}; 293 std::unique_lock lock{pipeline_cache};
303 graphics_cache.at(pipeline->GetCacheKey()) = std::move(pipeline); 294 graphics_cache.at(pipeline->GetCacheKey()) = std::move(pipeline);
304} 295}
@@ -339,9 +330,6 @@ void VKPipelineCache::OnShaderRemoval(Shader* shader) {
339 330
340std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> 331std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>>
341VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) { 332VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
342 auto& memory_manager = system.GPU().MemoryManager();
343 const auto& gpu = system.GPU().Maxwell3D();
344
345 Specialization specialization; 333 Specialization specialization;
346 if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points || 334 if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points ||
347 device.IsExtExtendedDynamicStateSupported()) { 335 device.IsExtExtendedDynamicStateSupported()) {
@@ -364,12 +352,12 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) {
364 const auto program_enum = static_cast<Maxwell::ShaderProgram>(index); 352 const auto program_enum = static_cast<Maxwell::ShaderProgram>(index);
365 353
366 // Skip stages that are not enabled 354 // Skip stages that are not enabled
367 if (!gpu.regs.IsShaderConfigEnabled(index)) { 355 if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
368 continue; 356 continue;
369 } 357 }
370 358
371 const GPUVAddr gpu_addr = GetShaderAddress(system, program_enum); 359 const GPUVAddr gpu_addr = GetShaderAddress(maxwell3d, program_enum);
372 const std::optional<VAddr> cpu_addr = memory_manager.GpuToCpuAddress(gpu_addr); 360 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
373 Shader* const shader = cpu_addr ? TryGet(*cpu_addr) : null_shader.get(); 361 Shader* const shader = cpu_addr ? TryGet(*cpu_addr) : null_shader.get();
374 362
375 const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 363 const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index c04829e77..1a31fd9f6 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -85,7 +85,8 @@ namespace Vulkan {
85 85
86class Shader { 86class Shader {
87public: 87public:
88 explicit Shader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, 88 explicit Shader(Tegra::Engines::ConstBufferEngineInterface& engine,
89 Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, VAddr cpu_addr,
89 VideoCommon::Shader::ProgramCode program_code, u32 main_offset); 90 VideoCommon::Shader::ProgramCode program_code, u32 main_offset);
90 ~Shader(); 91 ~Shader();
91 92
@@ -97,22 +98,19 @@ public:
97 return shader_ir; 98 return shader_ir;
98 } 99 }
99 100
100 const VideoCommon::Shader::Registry& GetRegistry() const {
101 return registry;
102 }
103
104 const VideoCommon::Shader::ShaderIR& GetIR() const { 101 const VideoCommon::Shader::ShaderIR& GetIR() const {
105 return shader_ir; 102 return shader_ir;
106 } 103 }
107 104
105 const VideoCommon::Shader::Registry& GetRegistry() const {
106 return registry;
107 }
108
108 const ShaderEntries& GetEntries() const { 109 const ShaderEntries& GetEntries() const {
109 return entries; 110 return entries;
110 } 111 }
111 112
112private: 113private:
113 static Tegra::Engines::ConstBufferEngineInterface& GetEngine(Core::System& system,
114 Tegra::Engines::ShaderType stage);
115
116 GPUVAddr gpu_addr{}; 114 GPUVAddr gpu_addr{};
117 VideoCommon::Shader::ProgramCode program_code; 115 VideoCommon::Shader::ProgramCode program_code;
118 VideoCommon::Shader::Registry registry; 116 VideoCommon::Shader::Registry registry;
@@ -122,9 +120,11 @@ private:
122 120
123class VKPipelineCache final : public VideoCommon::ShaderCache<Shader> { 121class VKPipelineCache final : public VideoCommon::ShaderCache<Shader> {
124public: 122public:
125 explicit VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, 123 explicit VKPipelineCache(RasterizerVulkan& rasterizer, Tegra::GPU& gpu,
126 const VKDevice& device, VKScheduler& scheduler, 124 Tegra::Engines::Maxwell3D& maxwell3d,
127 VKDescriptorPool& descriptor_pool, 125 Tegra::Engines::KeplerCompute& kepler_compute,
126 Tegra::MemoryManager& gpu_memory, const VKDevice& device,
127 VKScheduler& scheduler, VKDescriptorPool& descriptor_pool,
128 VKUpdateDescriptorQueue& update_descriptor_queue, 128 VKUpdateDescriptorQueue& update_descriptor_queue,
129 VKRenderPassCache& renderpass_cache); 129 VKRenderPassCache& renderpass_cache);
130 ~VKPipelineCache() override; 130 ~VKPipelineCache() override;
@@ -145,7 +145,11 @@ private:
145 std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> DecompileShaders( 145 std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> DecompileShaders(
146 const FixedPipelineState& fixed_state); 146 const FixedPipelineState& fixed_state);
147 147
148 Core::System& system; 148 Tegra::GPU& gpu;
149 Tegra::Engines::Maxwell3D& maxwell3d;
150 Tegra::Engines::KeplerCompute& kepler_compute;
151 Tegra::MemoryManager& gpu_memory;
152
149 const VKDevice& device; 153 const VKDevice& device;
150 VKScheduler& scheduler; 154 VKScheduler& scheduler;
151 VKDescriptorPool& descriptor_pool; 155 VKDescriptorPool& descriptor_pool;
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp
index 6cd63d090..5a97c959d 100644
--- a/src/video_core/renderer_vulkan/vk_query_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp
@@ -68,10 +68,11 @@ void QueryPool::Reserve(std::pair<VkQueryPool, u32> query) {
68 usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false; 68 usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false;
69} 69}
70 70
71VKQueryCache::VKQueryCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 71VKQueryCache::VKQueryCache(VideoCore::RasterizerInterface& rasterizer,
72 Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory,
72 const VKDevice& device, VKScheduler& scheduler) 73 const VKDevice& device, VKScheduler& scheduler)
73 : VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter, 74 : VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter,
74 QueryPool>{system, rasterizer}, 75 QueryPool>{rasterizer, maxwell3d, gpu_memory},
75 device{device}, scheduler{scheduler} { 76 device{device}, scheduler{scheduler} {
76 for (std::size_t i = 0; i < static_cast<std::size_t>(VideoCore::NumQueryTypes); ++i) { 77 for (std::size_t i = 0; i < static_cast<std::size_t>(VideoCore::NumQueryTypes); ++i) {
77 query_pools[i].Initialize(device, static_cast<VideoCore::QueryType>(i)); 78 query_pools[i].Initialize(device, static_cast<VideoCore::QueryType>(i));
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.h b/src/video_core/renderer_vulkan/vk_query_cache.h
index 40119e6d3..9be996e55 100644
--- a/src/video_core/renderer_vulkan/vk_query_cache.h
+++ b/src/video_core/renderer_vulkan/vk_query_cache.h
@@ -56,7 +56,8 @@ class VKQueryCache final
56 : public VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter, 56 : public VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter,
57 QueryPool> { 57 QueryPool> {
58public: 58public:
59 explicit VKQueryCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 59 explicit VKQueryCache(VideoCore::RasterizerInterface& rasterizer,
60 Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory,
60 const VKDevice& device, VKScheduler& scheduler); 61 const VKDevice& device, VKScheduler& scheduler);
61 ~VKQueryCache(); 62 ~VKQueryCache();
62 63
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index ff1b52eab..bafebe294 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -381,28 +381,30 @@ void RasterizerVulkan::DrawParameters::Draw(vk::CommandBuffer cmdbuf) const {
381 } 381 }
382} 382}
383 383
384RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer, 384RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu_,
385 VKScreenInfo& screen_info, const VKDevice& device, 385 Tegra::MemoryManager& gpu_memory_,
386 VKResourceManager& resource_manager, 386 Core::Memory::Memory& cpu_memory, VKScreenInfo& screen_info_,
387 VKMemoryManager& memory_manager, StateTracker& state_tracker, 387 const VKDevice& device_, VKResourceManager& resource_manager_,
388 VKScheduler& scheduler) 388 VKMemoryManager& memory_manager_, StateTracker& state_tracker_,
389 : RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer}, 389 VKScheduler& scheduler_)
390 screen_info{screen_info}, device{device}, resource_manager{resource_manager}, 390 : RasterizerAccelerated(cpu_memory), gpu(gpu_), gpu_memory(gpu_memory_),
391 memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler}, 391 maxwell3d(gpu.Maxwell3D()), kepler_compute(gpu.KeplerCompute()), screen_info(screen_info_),
392 device(device_), resource_manager(resource_manager_), memory_manager(memory_manager_),
393 state_tracker(state_tracker_), scheduler(scheduler_),
392 staging_pool(device, memory_manager, scheduler), descriptor_pool(device), 394 staging_pool(device, memory_manager, scheduler), descriptor_pool(device),
393 update_descriptor_queue(device, scheduler), renderpass_cache(device), 395 update_descriptor_queue(device, scheduler), renderpass_cache(device),
394 quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), 396 quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
395 quad_indexed_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), 397 quad_indexed_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
396 uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), 398 uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
397 texture_cache(system, *this, device, resource_manager, memory_manager, scheduler, 399 texture_cache(*this, maxwell3d, gpu_memory, device, resource_manager, memory_manager,
398 staging_pool), 400 scheduler, staging_pool),
399 pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, 401 pipeline_cache(*this, gpu, maxwell3d, kepler_compute, gpu_memory, device, scheduler,
400 renderpass_cache), 402 descriptor_pool, update_descriptor_queue, renderpass_cache),
401 buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), 403 buffer_cache(*this, gpu_memory, cpu_memory, device, memory_manager, scheduler, staging_pool),
402 sampler_cache(device), 404 sampler_cache(device), query_cache(*this, maxwell3d, gpu_memory, device, scheduler),
403 fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache), 405 fence_manager(*this, gpu, gpu_memory, texture_cache, buffer_cache, query_cache, device,
404 query_cache(system, *this, device, scheduler), 406 scheduler),
405 wfi_event{device.GetLogical().CreateNewEvent()}, async_shaders{renderer} { 407 wfi_event(device.GetLogical().CreateNewEvent()), async_shaders(emu_window) {
406 scheduler.SetQueryCache(query_cache); 408 scheduler.SetQueryCache(query_cache);
407 if (device.UseAsynchronousShaders()) { 409 if (device.UseAsynchronousShaders()) {
408 async_shaders.AllocateWorkers(); 410 async_shaders.AllocateWorkers();
@@ -414,15 +416,13 @@ RasterizerVulkan::~RasterizerVulkan() = default;
414void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { 416void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
415 MICROPROFILE_SCOPE(Vulkan_Drawing); 417 MICROPROFILE_SCOPE(Vulkan_Drawing);
416 418
419 SCOPE_EXIT({ gpu.TickWork(); });
417 FlushWork(); 420 FlushWork();
418 421
419 query_cache.UpdateCounters(); 422 query_cache.UpdateCounters();
420 423
421 SCOPE_EXIT({ system.GPU().TickWork(); });
422
423 const auto& gpu = system.GPU().Maxwell3D();
424 GraphicsPipelineCacheKey key; 424 GraphicsPipelineCacheKey key;
425 key.fixed_state.Fill(gpu.regs, device.IsExtExtendedDynamicStateSupported()); 425 key.fixed_state.Fill(maxwell3d.regs, device.IsExtExtendedDynamicStateSupported());
426 426
427 buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed)); 427 buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed));
428 428
@@ -480,8 +480,7 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
480void RasterizerVulkan::Clear() { 480void RasterizerVulkan::Clear() {
481 MICROPROFILE_SCOPE(Vulkan_Clearing); 481 MICROPROFILE_SCOPE(Vulkan_Clearing);
482 482
483 const auto& gpu = system.GPU().Maxwell3D(); 483 if (!maxwell3d.ShouldExecute()) {
484 if (!system.GPU().Maxwell3D().ShouldExecute()) {
485 return; 484 return;
486 } 485 }
487 486
@@ -490,7 +489,7 @@ void RasterizerVulkan::Clear() {
490 489
491 query_cache.UpdateCounters(); 490 query_cache.UpdateCounters();
492 491
493 const auto& regs = gpu.regs; 492 const auto& regs = maxwell3d.regs;
494 const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || 493 const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
495 regs.clear_buffers.A; 494 regs.clear_buffers.A;
496 const bool use_depth = regs.clear_buffers.Z; 495 const bool use_depth = regs.clear_buffers.Z;
@@ -559,7 +558,7 @@ void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) {
559 558
560 query_cache.UpdateCounters(); 559 query_cache.UpdateCounters();
561 560
562 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 561 const auto& launch_desc = kepler_compute.launch_description;
563 auto& pipeline = pipeline_cache.GetComputePipeline({ 562 auto& pipeline = pipeline_cache.GetComputePipeline({
564 .shader = code_addr, 563 .shader = code_addr,
565 .shared_memory_size = launch_desc.shared_alloc, 564 .shared_memory_size = launch_desc.shared_alloc,
@@ -655,16 +654,14 @@ void RasterizerVulkan::SyncGuestHost() {
655} 654}
656 655
657void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { 656void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) {
658 auto& gpu{system.GPU()};
659 if (!gpu.IsAsync()) { 657 if (!gpu.IsAsync()) {
660 gpu.MemoryManager().Write<u32>(addr, value); 658 gpu_memory.Write<u32>(addr, value);
661 return; 659 return;
662 } 660 }
663 fence_manager.SignalSemaphore(addr, value); 661 fence_manager.SignalSemaphore(addr, value);
664} 662}
665 663
666void RasterizerVulkan::SignalSyncPoint(u32 value) { 664void RasterizerVulkan::SignalSyncPoint(u32 value) {
667 auto& gpu{system.GPU()};
668 if (!gpu.IsAsync()) { 665 if (!gpu.IsAsync()) {
669 gpu.IncrementSyncPoint(value); 666 gpu.IncrementSyncPoint(value);
670 return; 667 return;
@@ -673,7 +670,6 @@ void RasterizerVulkan::SignalSyncPoint(u32 value) {
673} 670}
674 671
675void RasterizerVulkan::ReleaseFences() { 672void RasterizerVulkan::ReleaseFences() {
676 auto& gpu{system.GPU()};
677 if (!gpu.IsAsync()) { 673 if (!gpu.IsAsync()) {
678 return; 674 return;
679 } 675 }
@@ -751,10 +747,6 @@ bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config,
751 return true; 747 return true;
752} 748}
753 749
754void RasterizerVulkan::SetupDirtyFlags() {
755 state_tracker.Initialize();
756}
757
758void RasterizerVulkan::FlushWork() { 750void RasterizerVulkan::FlushWork() {
759 static constexpr u32 DRAWS_TO_DISPATCH = 4096; 751 static constexpr u32 DRAWS_TO_DISPATCH = 4096;
760 752
@@ -778,10 +770,9 @@ void RasterizerVulkan::FlushWork() {
778 770
779RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments(bool is_clear) { 771RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments(bool is_clear) {
780 MICROPROFILE_SCOPE(Vulkan_RenderTargets); 772 MICROPROFILE_SCOPE(Vulkan_RenderTargets);
781 auto& maxwell3d = system.GPU().Maxwell3D();
782 auto& dirty = maxwell3d.dirty.flags;
783 auto& regs = maxwell3d.regs;
784 773
774 const auto& regs = maxwell3d.regs;
775 auto& dirty = maxwell3d.dirty.flags;
785 const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets]; 776 const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets];
786 dirty[VideoCommon::Dirty::RenderTargets] = false; 777 dirty[VideoCommon::Dirty::RenderTargets] = false;
787 778
@@ -844,7 +835,7 @@ std::tuple<VkFramebuffer, VkExtent2D> RasterizerVulkan::ConfigureFramebuffers(
844 return true; 835 return true;
845 }; 836 };
846 837
847 const auto& regs = system.GPU().Maxwell3D().regs; 838 const auto& regs = maxwell3d.regs;
848 const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count); 839 const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count);
849 for (std::size_t index = 0; index < num_attachments; ++index) { 840 for (std::size_t index = 0; index < num_attachments; ++index) {
850 if (try_push(color_attachments[index])) { 841 if (try_push(color_attachments[index])) {
@@ -880,13 +871,12 @@ RasterizerVulkan::DrawParameters RasterizerVulkan::SetupGeometry(FixedPipelineSt
880 bool is_instanced) { 871 bool is_instanced) {
881 MICROPROFILE_SCOPE(Vulkan_Geometry); 872 MICROPROFILE_SCOPE(Vulkan_Geometry);
882 873
883 const auto& gpu = system.GPU().Maxwell3D(); 874 const auto& regs = maxwell3d.regs;
884 const auto& regs = gpu.regs;
885 875
886 SetupVertexArrays(buffer_bindings); 876 SetupVertexArrays(buffer_bindings);
887 877
888 const u32 base_instance = regs.vb_base_instance; 878 const u32 base_instance = regs.vb_base_instance;
889 const u32 num_instances = is_instanced ? gpu.mme_draw.instance_count : 1; 879 const u32 num_instances = is_instanced ? maxwell3d.mme_draw.instance_count : 1;
890 const u32 base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first; 880 const u32 base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first;
891 const u32 num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count; 881 const u32 num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count;
892 882
@@ -947,7 +937,7 @@ void RasterizerVulkan::SetupImageTransitions(
947} 937}
948 938
949void RasterizerVulkan::UpdateDynamicStates() { 939void RasterizerVulkan::UpdateDynamicStates() {
950 auto& regs = system.GPU().Maxwell3D().regs; 940 auto& regs = maxwell3d.regs;
951 UpdateViewportsState(regs); 941 UpdateViewportsState(regs);
952 UpdateScissorsState(regs); 942 UpdateScissorsState(regs);
953 UpdateDepthBias(regs); 943 UpdateDepthBias(regs);
@@ -968,7 +958,7 @@ void RasterizerVulkan::UpdateDynamicStates() {
968} 958}
969 959
970void RasterizerVulkan::BeginTransformFeedback() { 960void RasterizerVulkan::BeginTransformFeedback() {
971 const auto& regs = system.GPU().Maxwell3D().regs; 961 const auto& regs = maxwell3d.regs;
972 if (regs.tfb_enabled == 0) { 962 if (regs.tfb_enabled == 0) {
973 return; 963 return;
974 } 964 }
@@ -1000,7 +990,7 @@ void RasterizerVulkan::BeginTransformFeedback() {
1000} 990}
1001 991
1002void RasterizerVulkan::EndTransformFeedback() { 992void RasterizerVulkan::EndTransformFeedback() {
1003 const auto& regs = system.GPU().Maxwell3D().regs; 993 const auto& regs = maxwell3d.regs;
1004 if (regs.tfb_enabled == 0) { 994 if (regs.tfb_enabled == 0) {
1005 return; 995 return;
1006 } 996 }
@@ -1013,7 +1003,7 @@ void RasterizerVulkan::EndTransformFeedback() {
1013} 1003}
1014 1004
1015void RasterizerVulkan::SetupVertexArrays(BufferBindings& buffer_bindings) { 1005void RasterizerVulkan::SetupVertexArrays(BufferBindings& buffer_bindings) {
1016 const auto& regs = system.GPU().Maxwell3D().regs; 1006 const auto& regs = maxwell3d.regs;
1017 1007
1018 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { 1008 for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
1019 const auto& vertex_array = regs.vertex_array[index]; 1009 const auto& vertex_array = regs.vertex_array[index];
@@ -1039,7 +1029,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar
1039 if (params.num_vertices == 0) { 1029 if (params.num_vertices == 0) {
1040 return; 1030 return;
1041 } 1031 }
1042 const auto& regs = system.GPU().Maxwell3D().regs; 1032 const auto& regs = maxwell3d.regs;
1043 switch (regs.draw.topology) { 1033 switch (regs.draw.topology) {
1044 case Maxwell::PrimitiveTopology::Quads: { 1034 case Maxwell::PrimitiveTopology::Quads: {
1045 if (!params.is_indexed) { 1035 if (!params.is_indexed) {
@@ -1087,8 +1077,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar
1087 1077
1088void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, std::size_t stage) { 1078void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, std::size_t stage) {
1089 MICROPROFILE_SCOPE(Vulkan_ConstBuffers); 1079 MICROPROFILE_SCOPE(Vulkan_ConstBuffers);
1090 const auto& gpu = system.GPU().Maxwell3D(); 1080 const auto& shader_stage = maxwell3d.state.shader_stages[stage];
1091 const auto& shader_stage = gpu.state.shader_stages[stage];
1092 for (const auto& entry : entries.const_buffers) { 1081 for (const auto& entry : entries.const_buffers) {
1093 SetupConstBuffer(entry, shader_stage.const_buffers[entry.GetIndex()]); 1082 SetupConstBuffer(entry, shader_stage.const_buffers[entry.GetIndex()]);
1094 } 1083 }
@@ -1096,8 +1085,7 @@ void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, s
1096 1085
1097void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage) { 1086void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage) {
1098 MICROPROFILE_SCOPE(Vulkan_GlobalBuffers); 1087 MICROPROFILE_SCOPE(Vulkan_GlobalBuffers);
1099 auto& gpu{system.GPU()}; 1088 const auto& cbufs{maxwell3d.state.shader_stages[stage]};
1100 const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage]};
1101 1089
1102 for (const auto& entry : entries.global_buffers) { 1090 for (const auto& entry : entries.global_buffers) {
1103 const auto addr = cbufs.const_buffers[entry.GetCbufIndex()].address + entry.GetCbufOffset(); 1091 const auto addr = cbufs.const_buffers[entry.GetCbufIndex()].address + entry.GetCbufOffset();
@@ -1107,19 +1095,17 @@ void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries,
1107 1095
1108void RasterizerVulkan::SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage) { 1096void RasterizerVulkan::SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage) {
1109 MICROPROFILE_SCOPE(Vulkan_Textures); 1097 MICROPROFILE_SCOPE(Vulkan_Textures);
1110 const auto& gpu = system.GPU().Maxwell3D();
1111 for (const auto& entry : entries.uniform_texels) { 1098 for (const auto& entry : entries.uniform_texels) {
1112 const auto image = GetTextureInfo(gpu, entry, stage).tic; 1099 const auto image = GetTextureInfo(maxwell3d, entry, stage).tic;
1113 SetupUniformTexels(image, entry); 1100 SetupUniformTexels(image, entry);
1114 } 1101 }
1115} 1102}
1116 1103
1117void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage) { 1104void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage) {
1118 MICROPROFILE_SCOPE(Vulkan_Textures); 1105 MICROPROFILE_SCOPE(Vulkan_Textures);
1119 const auto& gpu = system.GPU().Maxwell3D();
1120 for (const auto& entry : entries.samplers) { 1106 for (const auto& entry : entries.samplers) {
1121 for (std::size_t i = 0; i < entry.size; ++i) { 1107 for (std::size_t i = 0; i < entry.size; ++i) {
1122 const auto texture = GetTextureInfo(gpu, entry, stage, i); 1108 const auto texture = GetTextureInfo(maxwell3d, entry, stage, i);
1123 SetupTexture(texture, entry); 1109 SetupTexture(texture, entry);
1124 } 1110 }
1125 } 1111 }
@@ -1127,25 +1113,23 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::
1127 1113
1128void RasterizerVulkan::SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage) { 1114void RasterizerVulkan::SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage) {
1129 MICROPROFILE_SCOPE(Vulkan_Textures); 1115 MICROPROFILE_SCOPE(Vulkan_Textures);
1130 const auto& gpu = system.GPU().Maxwell3D();
1131 for (const auto& entry : entries.storage_texels) { 1116 for (const auto& entry : entries.storage_texels) {
1132 const auto image = GetTextureInfo(gpu, entry, stage).tic; 1117 const auto image = GetTextureInfo(maxwell3d, entry, stage).tic;
1133 SetupStorageTexel(image, entry); 1118 SetupStorageTexel(image, entry);
1134 } 1119 }
1135} 1120}
1136 1121
1137void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { 1122void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) {
1138 MICROPROFILE_SCOPE(Vulkan_Images); 1123 MICROPROFILE_SCOPE(Vulkan_Images);
1139 const auto& gpu = system.GPU().Maxwell3D();
1140 for (const auto& entry : entries.images) { 1124 for (const auto& entry : entries.images) {
1141 const auto tic = GetTextureInfo(gpu, entry, stage).tic; 1125 const auto tic = GetTextureInfo(maxwell3d, entry, stage).tic;
1142 SetupImage(tic, entry); 1126 SetupImage(tic, entry);
1143 } 1127 }
1144} 1128}
1145 1129
1146void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) { 1130void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) {
1147 MICROPROFILE_SCOPE(Vulkan_ConstBuffers); 1131 MICROPROFILE_SCOPE(Vulkan_ConstBuffers);
1148 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 1132 const auto& launch_desc = kepler_compute.launch_description;
1149 for (const auto& entry : entries.const_buffers) { 1133 for (const auto& entry : entries.const_buffers) {
1150 const auto& config = launch_desc.const_buffer_config[entry.GetIndex()]; 1134 const auto& config = launch_desc.const_buffer_config[entry.GetIndex()];
1151 const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value(); 1135 const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value();
@@ -1159,7 +1143,7 @@ void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) {
1159 1143
1160void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) { 1144void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) {
1161 MICROPROFILE_SCOPE(Vulkan_GlobalBuffers); 1145 MICROPROFILE_SCOPE(Vulkan_GlobalBuffers);
1162 const auto cbufs{system.GPU().KeplerCompute().launch_description.const_buffer_config}; 1146 const auto& cbufs{kepler_compute.launch_description.const_buffer_config};
1163 for (const auto& entry : entries.global_buffers) { 1147 for (const auto& entry : entries.global_buffers) {
1164 const auto addr{cbufs[entry.GetCbufIndex()].Address() + entry.GetCbufOffset()}; 1148 const auto addr{cbufs[entry.GetCbufIndex()].Address() + entry.GetCbufOffset()};
1165 SetupGlobalBuffer(entry, addr); 1149 SetupGlobalBuffer(entry, addr);
@@ -1168,19 +1152,17 @@ void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) {
1168 1152
1169void RasterizerVulkan::SetupComputeUniformTexels(const ShaderEntries& entries) { 1153void RasterizerVulkan::SetupComputeUniformTexels(const ShaderEntries& entries) {
1170 MICROPROFILE_SCOPE(Vulkan_Textures); 1154 MICROPROFILE_SCOPE(Vulkan_Textures);
1171 const auto& gpu = system.GPU().KeplerCompute();
1172 for (const auto& entry : entries.uniform_texels) { 1155 for (const auto& entry : entries.uniform_texels) {
1173 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; 1156 const auto image = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic;
1174 SetupUniformTexels(image, entry); 1157 SetupUniformTexels(image, entry);
1175 } 1158 }
1176} 1159}
1177 1160
1178void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) { 1161void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) {
1179 MICROPROFILE_SCOPE(Vulkan_Textures); 1162 MICROPROFILE_SCOPE(Vulkan_Textures);
1180 const auto& gpu = system.GPU().KeplerCompute();
1181 for (const auto& entry : entries.samplers) { 1163 for (const auto& entry : entries.samplers) {
1182 for (std::size_t i = 0; i < entry.size; ++i) { 1164 for (std::size_t i = 0; i < entry.size; ++i) {
1183 const auto texture = GetTextureInfo(gpu, entry, ComputeShaderIndex, i); 1165 const auto texture = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex, i);
1184 SetupTexture(texture, entry); 1166 SetupTexture(texture, entry);
1185 } 1167 }
1186 } 1168 }
@@ -1188,18 +1170,16 @@ void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) {
1188 1170
1189void RasterizerVulkan::SetupComputeStorageTexels(const ShaderEntries& entries) { 1171void RasterizerVulkan::SetupComputeStorageTexels(const ShaderEntries& entries) {
1190 MICROPROFILE_SCOPE(Vulkan_Textures); 1172 MICROPROFILE_SCOPE(Vulkan_Textures);
1191 const auto& gpu = system.GPU().KeplerCompute();
1192 for (const auto& entry : entries.storage_texels) { 1173 for (const auto& entry : entries.storage_texels) {
1193 const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; 1174 const auto image = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic;
1194 SetupStorageTexel(image, entry); 1175 SetupStorageTexel(image, entry);
1195 } 1176 }
1196} 1177}
1197 1178
1198void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) { 1179void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) {
1199 MICROPROFILE_SCOPE(Vulkan_Images); 1180 MICROPROFILE_SCOPE(Vulkan_Images);
1200 const auto& gpu = system.GPU().KeplerCompute();
1201 for (const auto& entry : entries.images) { 1181 for (const auto& entry : entries.images) {
1202 const auto tic = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; 1182 const auto tic = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic;
1203 SetupImage(tic, entry); 1183 SetupImage(tic, entry);
1204 } 1184 }
1205} 1185}
@@ -1223,9 +1203,8 @@ void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry,
1223} 1203}
1224 1204
1225void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address) { 1205void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address) {
1226 auto& memory_manager{system.GPU().MemoryManager()}; 1206 const u64 actual_addr = gpu_memory.Read<u64>(address);
1227 const auto actual_addr = memory_manager.Read<u64>(address); 1207 const u32 size = gpu_memory.Read<u32>(address + 8);
1228 const auto size = memory_manager.Read<u32>(address + 8);
1229 1208
1230 if (size == 0) { 1209 if (size == 0) {
1231 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry 1210 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry
@@ -1508,7 +1487,7 @@ std::size_t RasterizerVulkan::CalculateComputeStreamBufferSize() const {
1508} 1487}
1509 1488
1510std::size_t RasterizerVulkan::CalculateVertexArraysSize() const { 1489std::size_t RasterizerVulkan::CalculateVertexArraysSize() const {
1511 const auto& regs = system.GPU().Maxwell3D().regs; 1490 const auto& regs = maxwell3d.regs;
1512 1491
1513 std::size_t size = 0; 1492 std::size_t size = 0;
1514 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { 1493 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
@@ -1523,9 +1502,8 @@ std::size_t RasterizerVulkan::CalculateVertexArraysSize() const {
1523} 1502}
1524 1503
1525std::size_t RasterizerVulkan::CalculateIndexBufferSize() const { 1504std::size_t RasterizerVulkan::CalculateIndexBufferSize() const {
1526 const auto& regs = system.GPU().Maxwell3D().regs; 1505 return static_cast<std::size_t>(maxwell3d.regs.index_array.count) *
1527 return static_cast<std::size_t>(regs.index_array.count) * 1506 static_cast<std::size_t>(maxwell3d.regs.index_array.FormatSizeInBytes());
1528 static_cast<std::size_t>(regs.index_array.FormatSizeInBytes());
1529} 1507}
1530 1508
1531std::size_t RasterizerVulkan::CalculateConstBufferSize( 1509std::size_t RasterizerVulkan::CalculateConstBufferSize(
@@ -1540,7 +1518,7 @@ std::size_t RasterizerVulkan::CalculateConstBufferSize(
1540} 1518}
1541 1519
1542RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const { 1520RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const {
1543 const auto& regs = system.GPU().Maxwell3D().regs; 1521 const auto& regs = maxwell3d.regs;
1544 const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count); 1522 const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count);
1545 1523
1546 RenderPassParams params; 1524 RenderPassParams params;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index f640ba649..16251d0f6 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -106,7 +106,8 @@ struct ImageView {
106 106
107class RasterizerVulkan final : public VideoCore::RasterizerAccelerated { 107class RasterizerVulkan final : public VideoCore::RasterizerAccelerated {
108public: 108public:
109 explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window, 109 explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
110 Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory,
110 VKScreenInfo& screen_info, const VKDevice& device, 111 VKScreenInfo& screen_info, const VKDevice& device,
111 VKResourceManager& resource_manager, VKMemoryManager& memory_manager, 112 VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
112 StateTracker& state_tracker, VKScheduler& scheduler); 113 StateTracker& state_tracker, VKScheduler& scheduler);
@@ -135,7 +136,6 @@ public:
135 const Tegra::Engines::Fermi2D::Config& copy_config) override; 136 const Tegra::Engines::Fermi2D::Config& copy_config) override;
136 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 137 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
137 u32 pixel_stride) override; 138 u32 pixel_stride) override;
138 void SetupDirtyFlags() override;
139 139
140 VideoCommon::Shader::AsyncShaders& GetAsyncShaders() { 140 VideoCommon::Shader::AsyncShaders& GetAsyncShaders() {
141 return async_shaders; 141 return async_shaders;
@@ -279,8 +279,11 @@ private:
279 279
280 VkBuffer DefaultBuffer(); 280 VkBuffer DefaultBuffer();
281 281
282 Core::System& system; 282 Tegra::GPU& gpu;
283 Core::Frontend::EmuWindow& render_window; 283 Tegra::MemoryManager& gpu_memory;
284 Tegra::Engines::Maxwell3D& maxwell3d;
285 Tegra::Engines::KeplerCompute& kepler_compute;
286
284 VKScreenInfo& screen_info; 287 VKScreenInfo& screen_info;
285 const VKDevice& device; 288 const VKDevice& device;
286 VKResourceManager& resource_manager; 289 VKResourceManager& resource_manager;
@@ -300,8 +303,8 @@ private:
300 VKPipelineCache pipeline_cache; 303 VKPipelineCache pipeline_cache;
301 VKBufferCache buffer_cache; 304 VKBufferCache buffer_cache;
302 VKSamplerCache sampler_cache; 305 VKSamplerCache sampler_cache;
303 VKFenceManager fence_manager;
304 VKQueryCache query_cache; 306 VKQueryCache query_cache;
307 VKFenceManager fence_manager;
305 308
306 vk::Buffer default_buffer; 309 vk::Buffer default_buffer;
307 VKMemoryCommit default_buffer_commit; 310 VKMemoryCommit default_buffer_commit;
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index 4bd1009f9..5d2c4a796 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -132,12 +132,9 @@ void SetupDirtyStencilTestEnable(Tables& tables) {
132 132
133} // Anonymous namespace 133} // Anonymous namespace
134 134
135StateTracker::StateTracker(Core::System& system) 135StateTracker::StateTracker(Tegra::GPU& gpu)
136 : system{system}, invalidation_flags{MakeInvalidationFlags()} {} 136 : flags{gpu.Maxwell3D().dirty.flags}, invalidation_flags{MakeInvalidationFlags()} {
137 137 auto& tables = gpu.Maxwell3D().dirty.tables;
138void StateTracker::Initialize() {
139 auto& dirty = system.GPU().Maxwell3D().dirty;
140 auto& tables = dirty.tables;
141 SetupDirtyRenderTargets(tables); 138 SetupDirtyRenderTargets(tables);
142 SetupDirtyViewports(tables); 139 SetupDirtyViewports(tables);
143 SetupDirtyScissors(tables); 140 SetupDirtyScissors(tables);
@@ -155,9 +152,4 @@ void StateTracker::Initialize() {
155 SetupDirtyStencilTestEnable(tables); 152 SetupDirtyStencilTestEnable(tables);
156} 153}
157 154
158void StateTracker::InvalidateCommandBufferState() {
159 system.GPU().Maxwell3D().dirty.flags |= invalidation_flags;
160 current_topology = INVALID_TOPOLOGY;
161}
162
163} // namespace Vulkan 155} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h
index 13a6ce786..1de789e57 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.h
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.h
@@ -45,11 +45,12 @@ class StateTracker {
45 using Maxwell = Tegra::Engines::Maxwell3D::Regs; 45 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
46 46
47public: 47public:
48 explicit StateTracker(Core::System& system); 48 explicit StateTracker(Tegra::GPU& gpu);
49 49
50 void Initialize(); 50 void InvalidateCommandBufferState() {
51 51 flags |= invalidation_flags;
52 void InvalidateCommandBufferState(); 52 current_topology = INVALID_TOPOLOGY;
53 }
53 54
54 bool TouchViewports() { 55 bool TouchViewports() {
55 return Exchange(Dirty::Viewports, false); 56 return Exchange(Dirty::Viewports, false);
@@ -121,13 +122,12 @@ private:
121 static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u); 122 static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u);
122 123
123 bool Exchange(std::size_t id, bool new_value) const noexcept { 124 bool Exchange(std::size_t id, bool new_value) const noexcept {
124 auto& flags = system.GPU().Maxwell3D().dirty.flags;
125 const bool is_dirty = flags[id]; 125 const bool is_dirty = flags[id];
126 flags[id] = new_value; 126 flags[id] = new_value;
127 return is_dirty; 127 return is_dirty;
128 } 128 }
129 129
130 Core::System& system; 130 Tegra::Engines::Maxwell3D::DirtyState::Flags& flags;
131 Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags; 131 Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags;
132 Maxwell::PrimitiveTopology current_topology = INVALID_TOPOLOGY; 132 Maxwell::PrimitiveTopology current_topology = INVALID_TOPOLOGY;
133}; 133};
diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
index a5526a3f5..3c9171a5e 100644
--- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
+++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp
@@ -57,9 +57,9 @@ u32 GetMemoryType(const VkPhysicalDeviceMemoryProperties& properties,
57 57
58} // Anonymous namespace 58} // Anonymous namespace
59 59
60VKStreamBuffer::VKStreamBuffer(const VKDevice& device, VKScheduler& scheduler, 60VKStreamBuffer::VKStreamBuffer(const VKDevice& device_, VKScheduler& scheduler_,
61 VkBufferUsageFlags usage) 61 VkBufferUsageFlags usage)
62 : device{device}, scheduler{scheduler} { 62 : device{device_}, scheduler{scheduler_} {
63 CreateBuffers(usage); 63 CreateBuffers(usage);
64 ReserveWatches(current_watches, WATCHES_INITIAL_RESERVE); 64 ReserveWatches(current_watches, WATCHES_INITIAL_RESERVE);
65 ReserveWatches(previous_watches, WATCHES_INITIAL_RESERVE); 65 ReserveWatches(previous_watches, WATCHES_INITIAL_RESERVE);
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 2c6f54101..06182d909 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -188,13 +188,13 @@ u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source, Tegra::Texture::Swizzl
188 188
189} // Anonymous namespace 189} // Anonymous namespace
190 190
191CachedSurface::CachedSurface(Core::System& system, const VKDevice& device, 191CachedSurface::CachedSurface(const VKDevice& device, VKResourceManager& resource_manager,
192 VKResourceManager& resource_manager, VKMemoryManager& memory_manager, 192 VKMemoryManager& memory_manager, VKScheduler& scheduler,
193 VKScheduler& scheduler, VKStagingBufferPool& staging_pool, 193 VKStagingBufferPool& staging_pool, GPUVAddr gpu_addr,
194 GPUVAddr gpu_addr, const SurfaceParams& params) 194 const SurfaceParams& params)
195 : SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, system{system}, 195 : SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, device{device},
196 device{device}, resource_manager{resource_manager}, 196 resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler},
197 memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{staging_pool} { 197 staging_pool{staging_pool} {
198 if (params.IsBuffer()) { 198 if (params.IsBuffer()) {
199 buffer = CreateBuffer(device, params, host_memory_size); 199 buffer = CreateBuffer(device, params, host_memory_size);
200 commit = memory_manager.Commit(buffer, false); 200 commit = memory_manager.Commit(buffer, false);
@@ -490,19 +490,21 @@ VkImageView CachedSurfaceView::GetAttachment() {
490 return *render_target; 490 return *render_target;
491} 491}
492 492
493VKTextureCache::VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 493VKTextureCache::VKTextureCache(VideoCore::RasterizerInterface& rasterizer,
494 const VKDevice& device, VKResourceManager& resource_manager, 494 Tegra::Engines::Maxwell3D& maxwell3d,
495 VKMemoryManager& memory_manager, VKScheduler& scheduler, 495 Tegra::MemoryManager& gpu_memory, const VKDevice& device_,
496 VKStagingBufferPool& staging_pool) 496 VKResourceManager& resource_manager_,
497 : TextureCache(system, rasterizer, device.IsOptimalAstcSupported()), device{device}, 497 VKMemoryManager& memory_manager_, VKScheduler& scheduler_,
498 resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler}, 498 VKStagingBufferPool& staging_pool_)
499 staging_pool{staging_pool} {} 499 : TextureCache(rasterizer, maxwell3d, gpu_memory, device_.IsOptimalAstcSupported()),
500 device{device_}, resource_manager{resource_manager_},
501 memory_manager{memory_manager_}, scheduler{scheduler_}, staging_pool{staging_pool_} {}
500 502
501VKTextureCache::~VKTextureCache() = default; 503VKTextureCache::~VKTextureCache() = default;
502 504
503Surface VKTextureCache::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) { 505Surface VKTextureCache::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) {
504 return std::make_shared<CachedSurface>(system, device, resource_manager, memory_manager, 506 return std::make_shared<CachedSurface>(device, resource_manager, memory_manager, scheduler,
505 scheduler, staging_pool, gpu_addr, params); 507 staging_pool, gpu_addr, params);
506} 508}
507 509
508void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface, 510void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface,
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 807e26c8a..e47d02c41 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -15,10 +15,6 @@
15#include "video_core/texture_cache/surface_base.h" 15#include "video_core/texture_cache/surface_base.h"
16#include "video_core/texture_cache/texture_cache.h" 16#include "video_core/texture_cache/texture_cache.h"
17 17
18namespace Core {
19class System;
20}
21
22namespace VideoCore { 18namespace VideoCore {
23class RasterizerInterface; 19class RasterizerInterface;
24} 20}
@@ -45,10 +41,10 @@ class CachedSurface final : public VideoCommon::SurfaceBase<View> {
45 friend CachedSurfaceView; 41 friend CachedSurfaceView;
46 42
47public: 43public:
48 explicit CachedSurface(Core::System& system, const VKDevice& device, 44 explicit CachedSurface(const VKDevice& device, VKResourceManager& resource_manager,
49 VKResourceManager& resource_manager, VKMemoryManager& memory_manager, 45 VKMemoryManager& memory_manager, VKScheduler& scheduler,
50 VKScheduler& scheduler, VKStagingBufferPool& staging_pool, 46 VKStagingBufferPool& staging_pool, GPUVAddr gpu_addr,
51 GPUVAddr gpu_addr, const SurfaceParams& params); 47 const SurfaceParams& params);
52 ~CachedSurface(); 48 ~CachedSurface();
53 49
54 void UploadTexture(const std::vector<u8>& staging_buffer) override; 50 void UploadTexture(const std::vector<u8>& staging_buffer) override;
@@ -101,7 +97,6 @@ private:
101 97
102 VkImageSubresourceRange GetImageSubresourceRange() const; 98 VkImageSubresourceRange GetImageSubresourceRange() const;
103 99
104 Core::System& system;
105 const VKDevice& device; 100 const VKDevice& device;
106 VKResourceManager& resource_manager; 101 VKResourceManager& resource_manager;
107 VKMemoryManager& memory_manager; 102 VKMemoryManager& memory_manager;
@@ -201,7 +196,8 @@ private:
201 196
202class VKTextureCache final : public TextureCacheBase { 197class VKTextureCache final : public TextureCacheBase {
203public: 198public:
204 explicit VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 199 explicit VKTextureCache(VideoCore::RasterizerInterface& rasterizer,
200 Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory,
205 const VKDevice& device, VKResourceManager& resource_manager, 201 const VKDevice& device, VKResourceManager& resource_manager,
206 VKMemoryManager& memory_manager, VKScheduler& scheduler, 202 VKMemoryManager& memory_manager, VKScheduler& scheduler,
207 VKStagingBufferPool& staging_pool); 203 VKStagingBufferPool& staging_pool);
diff --git a/src/video_core/shader/memory_util.cpp b/src/video_core/shader/memory_util.cpp
index 5071c83ca..e18ccba8e 100644
--- a/src/video_core/shader/memory_util.cpp
+++ b/src/video_core/shader/memory_util.cpp
@@ -16,11 +16,10 @@
16 16
17namespace VideoCommon::Shader { 17namespace VideoCommon::Shader {
18 18
19GPUVAddr GetShaderAddress(Core::System& system, 19GPUVAddr GetShaderAddress(Tegra::Engines::Maxwell3D& maxwell3d,
20 Tegra::Engines::Maxwell3D::Regs::ShaderProgram program) { 20 Tegra::Engines::Maxwell3D::Regs::ShaderProgram program) {
21 const auto& gpu{system.GPU().Maxwell3D()}; 21 const auto& shader_config{maxwell3d.regs.shader_config[static_cast<std::size_t>(program)]};
22 const auto& shader_config{gpu.regs.shader_config[static_cast<std::size_t>(program)]}; 22 return maxwell3d.regs.code_address.CodeAddress() + shader_config.offset;
23 return gpu.regs.code_address.CodeAddress() + shader_config.offset;
24} 23}
25 24
26bool IsSchedInstruction(std::size_t offset, std::size_t main_offset) { 25bool IsSchedInstruction(std::size_t offset, std::size_t main_offset) {
diff --git a/src/video_core/shader/memory_util.h b/src/video_core/shader/memory_util.h
index be90d24fd..4624d38e6 100644
--- a/src/video_core/shader/memory_util.h
+++ b/src/video_core/shader/memory_util.h
@@ -11,10 +11,6 @@
11#include "video_core/engines/maxwell_3d.h" 11#include "video_core/engines/maxwell_3d.h"
12#include "video_core/engines/shader_type.h" 12#include "video_core/engines/shader_type.h"
13 13
14namespace Core {
15class System;
16}
17
18namespace Tegra { 14namespace Tegra {
19class MemoryManager; 15class MemoryManager;
20} 16}
@@ -27,7 +23,7 @@ constexpr u32 STAGE_MAIN_OFFSET = 10;
27constexpr u32 KERNEL_MAIN_OFFSET = 0; 23constexpr u32 KERNEL_MAIN_OFFSET = 0;
28 24
29/// Gets the address for the specified shader stage program 25/// Gets the address for the specified shader stage program
30GPUVAddr GetShaderAddress(Core::System& system, 26GPUVAddr GetShaderAddress(Tegra::Engines::Maxwell3D& maxwell3d,
31 Tegra::Engines::Maxwell3D::Regs::ShaderProgram program); 27 Tegra::Engines::Maxwell3D::Regs::ShaderProgram program);
32 28
33/// Gets if the current instruction offset is a scheduler instruction 29/// Gets if the current instruction offset is a scheduler instruction
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp
index e614a92df..e8515321b 100644
--- a/src/video_core/texture_cache/surface_params.cpp
+++ b/src/video_core/texture_cache/surface_params.cpp
@@ -163,13 +163,11 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl
163 return params; 163 return params;
164} 164}
165 165
166SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) { 166SurfaceParams SurfaceParams::CreateForDepthBuffer(Tegra::Engines::Maxwell3D& maxwell3d) {
167 const auto& regs = system.GPU().Maxwell3D().regs; 167 const auto& regs = maxwell3d.regs;
168
169 const auto block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U); 168 const auto block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U);
170 const bool is_layered = regs.zeta_layers > 1 && block_depth == 0; 169 const bool is_layered = regs.zeta_layers > 1 && block_depth == 0;
171 const auto pixel_format = PixelFormatFromDepthFormat(regs.zeta.format); 170 const auto pixel_format = PixelFormatFromDepthFormat(regs.zeta.format);
172
173 return { 171 return {
174 .is_tiled = regs.zeta.memory_layout.type == 172 .is_tiled = regs.zeta.memory_layout.type ==
175 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear, 173 Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear,
@@ -191,8 +189,9 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) {
191 }; 189 };
192} 190}
193 191
194SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::size_t index) { 192SurfaceParams SurfaceParams::CreateForFramebuffer(Tegra::Engines::Maxwell3D& maxwell3d,
195 const auto& config{system.GPU().Maxwell3D().regs.rt[index]}; 193 std::size_t index) {
194 const auto& config{maxwell3d.regs.rt[index]};
196 SurfaceParams params; 195 SurfaceParams params;
197 params.is_tiled = 196 params.is_tiled =
198 config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; 197 config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;
diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h
index 118aa689e..4466c3c34 100644
--- a/src/video_core/texture_cache/surface_params.h
+++ b/src/video_core/texture_cache/surface_params.h
@@ -33,10 +33,11 @@ public:
33 const VideoCommon::Shader::Image& entry); 33 const VideoCommon::Shader::Image& entry);
34 34
35 /// Creates SurfaceCachedParams for a depth buffer configuration. 35 /// Creates SurfaceCachedParams for a depth buffer configuration.
36 static SurfaceParams CreateForDepthBuffer(Core::System& system); 36 static SurfaceParams CreateForDepthBuffer(Tegra::Engines::Maxwell3D& maxwell3d);
37 37
38 /// Creates SurfaceCachedParams from a framebuffer configuration. 38 /// Creates SurfaceCachedParams from a framebuffer configuration.
39 static SurfaceParams CreateForFramebuffer(Core::System& system, std::size_t index); 39 static SurfaceParams CreateForFramebuffer(Tegra::Engines::Maxwell3D& maxwell3d,
40 std::size_t index);
40 41
41 /// Creates SurfaceCachedParams from a Fermi2D surface configuration. 42 /// Creates SurfaceCachedParams from a Fermi2D surface configuration.
42 static SurfaceParams CreateForFermiCopySurface( 43 static SurfaceParams CreateForFermiCopySurface(
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 96c4e4cc2..ea835c59f 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -135,8 +135,7 @@ public:
135 return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); 135 return GetNullSurface(SurfaceParams::ExpectedTarget(entry));
136 } 136 }
137 137
138 const std::optional<VAddr> cpu_addr = 138 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
139 system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr);
140 if (!cpu_addr) { 139 if (!cpu_addr) {
141 return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); 140 return GetNullSurface(SurfaceParams::ExpectedTarget(entry));
142 } 141 }
@@ -160,8 +159,7 @@ public:
160 if (!gpu_addr) { 159 if (!gpu_addr) {
161 return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); 160 return GetNullSurface(SurfaceParams::ExpectedTarget(entry));
162 } 161 }
163 const std::optional<VAddr> cpu_addr = 162 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
164 system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr);
165 if (!cpu_addr) { 163 if (!cpu_addr) {
166 return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); 164 return GetNullSurface(SurfaceParams::ExpectedTarget(entry));
167 } 165 }
@@ -183,11 +181,11 @@ public:
183 181
184 TView GetDepthBufferSurface(bool preserve_contents) { 182 TView GetDepthBufferSurface(bool preserve_contents) {
185 std::lock_guard lock{mutex}; 183 std::lock_guard lock{mutex};
186 auto& maxwell3d = system.GPU().Maxwell3D(); 184 auto& dirty = maxwell3d.dirty;
187 if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ZetaBuffer]) { 185 if (!dirty.flags[VideoCommon::Dirty::ZetaBuffer]) {
188 return depth_buffer.view; 186 return depth_buffer.view;
189 } 187 }
190 maxwell3d.dirty.flags[VideoCommon::Dirty::ZetaBuffer] = false; 188 dirty.flags[VideoCommon::Dirty::ZetaBuffer] = false;
191 189
192 const auto& regs{maxwell3d.regs}; 190 const auto& regs{maxwell3d.regs};
193 const auto gpu_addr{regs.zeta.Address()}; 191 const auto gpu_addr{regs.zeta.Address()};
@@ -195,13 +193,12 @@ public:
195 SetEmptyDepthBuffer(); 193 SetEmptyDepthBuffer();
196 return {}; 194 return {};
197 } 195 }
198 const std::optional<VAddr> cpu_addr = 196 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
199 system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr);
200 if (!cpu_addr) { 197 if (!cpu_addr) {
201 SetEmptyDepthBuffer(); 198 SetEmptyDepthBuffer();
202 return {}; 199 return {};
203 } 200 }
204 const auto depth_params{SurfaceParams::CreateForDepthBuffer(system)}; 201 const auto depth_params{SurfaceParams::CreateForDepthBuffer(maxwell3d)};
205 auto surface_view = GetSurface(gpu_addr, *cpu_addr, depth_params, preserve_contents, true); 202 auto surface_view = GetSurface(gpu_addr, *cpu_addr, depth_params, preserve_contents, true);
206 if (depth_buffer.target) 203 if (depth_buffer.target)
207 depth_buffer.target->MarkAsRenderTarget(false, NO_RT); 204 depth_buffer.target->MarkAsRenderTarget(false, NO_RT);
@@ -215,7 +212,6 @@ public:
215 TView GetColorBufferSurface(std::size_t index, bool preserve_contents) { 212 TView GetColorBufferSurface(std::size_t index, bool preserve_contents) {
216 std::lock_guard lock{mutex}; 213 std::lock_guard lock{mutex};
217 ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); 214 ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets);
218 auto& maxwell3d = system.GPU().Maxwell3D();
219 if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ColorBuffer0 + index]) { 215 if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ColorBuffer0 + index]) {
220 return render_targets[index].view; 216 return render_targets[index].view;
221 } 217 }
@@ -235,15 +231,14 @@ public:
235 return {}; 231 return {};
236 } 232 }
237 233
238 const std::optional<VAddr> cpu_addr = 234 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
239 system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr);
240 if (!cpu_addr) { 235 if (!cpu_addr) {
241 SetEmptyColorBuffer(index); 236 SetEmptyColorBuffer(index);
242 return {}; 237 return {};
243 } 238 }
244 239
245 auto surface_view = 240 auto surface_view =
246 GetSurface(gpu_addr, *cpu_addr, SurfaceParams::CreateForFramebuffer(system, index), 241 GetSurface(gpu_addr, *cpu_addr, SurfaceParams::CreateForFramebuffer(maxwell3d, index),
247 preserve_contents, true); 242 preserve_contents, true);
248 if (render_targets[index].target) { 243 if (render_targets[index].target) {
249 auto& surface = render_targets[index].target; 244 auto& surface = render_targets[index].target;
@@ -300,9 +295,8 @@ public:
300 const GPUVAddr dst_gpu_addr = dst_config.Address(); 295 const GPUVAddr dst_gpu_addr = dst_config.Address();
301 DeduceBestBlit(src_params, dst_params, src_gpu_addr, dst_gpu_addr); 296 DeduceBestBlit(src_params, dst_params, src_gpu_addr, dst_gpu_addr);
302 297
303 const auto& memory_manager = system.GPU().MemoryManager(); 298 const std::optional<VAddr> dst_cpu_addr = gpu_memory.GpuToCpuAddress(dst_gpu_addr);
304 const std::optional<VAddr> dst_cpu_addr = memory_manager.GpuToCpuAddress(dst_gpu_addr); 299 const std::optional<VAddr> src_cpu_addr = gpu_memory.GpuToCpuAddress(src_gpu_addr);
305 const std::optional<VAddr> src_cpu_addr = memory_manager.GpuToCpuAddress(src_gpu_addr);
306 std::pair dst_surface = GetSurface(dst_gpu_addr, *dst_cpu_addr, dst_params, true, false); 300 std::pair dst_surface = GetSurface(dst_gpu_addr, *dst_cpu_addr, dst_params, true, false);
307 TView src_surface = GetSurface(src_gpu_addr, *src_cpu_addr, src_params, true, false).second; 301 TView src_surface = GetSurface(src_gpu_addr, *src_cpu_addr, src_params, true, false).second;
308 ImageBlit(src_surface, dst_surface.second, copy_config); 302 ImageBlit(src_surface, dst_surface.second, copy_config);
@@ -358,9 +352,11 @@ public:
358 } 352 }
359 353
360protected: 354protected:
361 explicit TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 355 explicit TextureCache(VideoCore::RasterizerInterface& rasterizer_,
362 bool is_astc_supported) 356 Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_,
363 : system{system}, is_astc_supported{is_astc_supported}, rasterizer{rasterizer} { 357 bool is_astc_supported_)
358 : is_astc_supported{is_astc_supported_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_},
359 gpu_memory{gpu_memory_} {
364 for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { 360 for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
365 SetEmptyColorBuffer(i); 361 SetEmptyColorBuffer(i);
366 } 362 }
@@ -395,7 +391,7 @@ protected:
395 virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0; 391 virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0;
396 392
397 void ManageRenderTargetUnregister(TSurface& surface) { 393 void ManageRenderTargetUnregister(TSurface& surface) {
398 auto& dirty = system.GPU().Maxwell3D().dirty; 394 auto& dirty = maxwell3d.dirty;
399 const u32 index = surface->GetRenderTarget(); 395 const u32 index = surface->GetRenderTarget();
400 if (index == DEPTH_RT) { 396 if (index == DEPTH_RT) {
401 dirty.flags[VideoCommon::Dirty::ZetaBuffer] = true; 397 dirty.flags[VideoCommon::Dirty::ZetaBuffer] = true;
@@ -408,8 +404,7 @@ protected:
408 void Register(TSurface surface) { 404 void Register(TSurface surface) {
409 const GPUVAddr gpu_addr = surface->GetGpuAddr(); 405 const GPUVAddr gpu_addr = surface->GetGpuAddr();
410 const std::size_t size = surface->GetSizeInBytes(); 406 const std::size_t size = surface->GetSizeInBytes();
411 const std::optional<VAddr> cpu_addr = 407 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
412 system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr);
413 if (!cpu_addr) { 408 if (!cpu_addr) {
414 LOG_CRITICAL(HW_GPU, "Failed to register surface with unmapped gpu_address 0x{:016x}", 409 LOG_CRITICAL(HW_GPU, "Failed to register surface with unmapped gpu_address 0x{:016x}",
415 gpu_addr); 410 gpu_addr);
@@ -459,7 +454,6 @@ protected:
459 return new_surface; 454 return new_surface;
460 } 455 }
461 456
462 Core::System& system;
463 const bool is_astc_supported; 457 const bool is_astc_supported;
464 458
465private: 459private:
@@ -954,8 +948,7 @@ private:
954 * @param params The parameters on the candidate surface. 948 * @param params The parameters on the candidate surface.
955 **/ 949 **/
956 Deduction DeduceSurface(const GPUVAddr gpu_addr, const SurfaceParams& params) { 950 Deduction DeduceSurface(const GPUVAddr gpu_addr, const SurfaceParams& params) {
957 const std::optional<VAddr> cpu_addr = 951 const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
958 system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr);
959 952
960 if (!cpu_addr) { 953 if (!cpu_addr) {
961 Deduction result{}; 954 Deduction result{};
@@ -1112,7 +1105,7 @@ private:
1112 1105
1113 void LoadSurface(const TSurface& surface) { 1106 void LoadSurface(const TSurface& surface) {
1114 staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes()); 1107 staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes());
1115 surface->LoadBuffer(system.GPU().MemoryManager(), staging_cache); 1108 surface->LoadBuffer(gpu_memory, staging_cache);
1116 surface->UploadTexture(staging_cache.GetBuffer(0)); 1109 surface->UploadTexture(staging_cache.GetBuffer(0));
1117 surface->MarkAsModified(false, Tick()); 1110 surface->MarkAsModified(false, Tick());
1118 } 1111 }
@@ -1123,7 +1116,7 @@ private:
1123 } 1116 }
1124 staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes()); 1117 staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes());
1125 surface->DownloadTexture(staging_cache.GetBuffer(0)); 1118 surface->DownloadTexture(staging_cache.GetBuffer(0));
1126 surface->FlushBuffer(system.GPU().MemoryManager(), staging_cache); 1119 surface->FlushBuffer(gpu_memory, staging_cache);
1127 surface->MarkAsModified(false, Tick()); 1120 surface->MarkAsModified(false, Tick());
1128 } 1121 }
1129 1122
@@ -1253,6 +1246,8 @@ private:
1253 } 1246 }
1254 1247
1255 VideoCore::RasterizerInterface& rasterizer; 1248 VideoCore::RasterizerInterface& rasterizer;
1249 Tegra::Engines::Maxwell3D& maxwell3d;
1250 Tegra::MemoryManager& gpu_memory;
1256 1251
1257 FormatLookupTable format_lookup_table; 1252 FormatLookupTable format_lookup_table;
1258 FormatCompatibility format_compatibility; 1253 FormatCompatibility format_compatibility;
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index 4e3a092c7..a14df06a3 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -21,14 +21,17 @@ namespace {
21std::unique_ptr<VideoCore::RendererBase> CreateRenderer( 21std::unique_ptr<VideoCore::RendererBase> CreateRenderer(
22 Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, 22 Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
23 std::unique_ptr<Core::Frontend::GraphicsContext> context) { 23 std::unique_ptr<Core::Frontend::GraphicsContext> context) {
24 auto& telemetry_session = system.TelemetrySession();
25 auto& cpu_memory = system.Memory();
26
24 switch (Settings::values.renderer_backend.GetValue()) { 27 switch (Settings::values.renderer_backend.GetValue()) {
25 case Settings::RendererBackend::OpenGL: 28 case Settings::RendererBackend::OpenGL:
26 return std::make_unique<OpenGL::RendererOpenGL>(system, emu_window, gpu, 29 return std::make_unique<OpenGL::RendererOpenGL>(telemetry_session, emu_window, cpu_memory,
27 std::move(context)); 30 gpu, std::move(context));
28#ifdef HAS_VULKAN 31#ifdef HAS_VULKAN
29 case Settings::RendererBackend::Vulkan: 32 case Settings::RendererBackend::Vulkan:
30 return std::make_unique<Vulkan::RendererVulkan>(system, emu_window, gpu, 33 return std::make_unique<Vulkan::RendererVulkan>(telemetry_session, emu_window, cpu_memory,
31 std::move(context)); 34 gpu, std::move(context));
32#endif 35#endif
33 default: 36 default:
34 return nullptr; 37 return nullptr;
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 21707e451..caa2d06d3 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -30,6 +30,7 @@
30#include "common/scope_exit.h" 30#include "common/scope_exit.h"
31#include "core/core.h" 31#include "core/core.h"
32#include "core/frontend/framebuffer_layout.h" 32#include "core/frontend/framebuffer_layout.h"
33#include "core/hle/kernel/process.h"
33#include "core/settings.h" 34#include "core/settings.h"
34#include "input_common/keyboard.h" 35#include "input_common/keyboard.h"
35#include "input_common/main.h" 36#include "input_common/main.h"
@@ -63,7 +64,8 @@ void EmuThread::run() {
63 emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); 64 emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
64 65
65 system.Renderer().Rasterizer().LoadDiskResources( 66 system.Renderer().Rasterizer().LoadDiskResources(
66 stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { 67 system.CurrentProcess()->GetTitleID(), stop_run,
68 [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
67 emit LoadProgress(stage, value, total); 69 emit LoadProgress(stage, value, total);
68 }); 70 });
69 71
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 4f00c804d..e960b5413 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -26,6 +26,7 @@
26#include "core/file_sys/registered_cache.h" 26#include "core/file_sys/registered_cache.h"
27#include "core/file_sys/vfs_real.h" 27#include "core/file_sys/vfs_real.h"
28#include "core/gdbstub/gdbstub.h" 28#include "core/gdbstub/gdbstub.h"
29#include "core/hle/kernel/process.h"
29#include "core/hle/service/filesystem/filesystem.h" 30#include "core/hle/service/filesystem/filesystem.h"
30#include "core/loader/loader.h" 31#include "core/loader/loader.h"
31#include "core/settings.h" 32#include "core/settings.h"
@@ -235,7 +236,9 @@ int main(int argc, char** argv) {
235 // Core is loaded, start the GPU (makes the GPU contexts current to this thread) 236 // Core is loaded, start the GPU (makes the GPU contexts current to this thread)
236 system.GPU().Start(); 237 system.GPU().Start();
237 238
238 system.Renderer().Rasterizer().LoadDiskResources(); 239 system.Renderer().Rasterizer().LoadDiskResources(
240 system.CurrentProcess()->GetTitleID(), false,
241 [](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
239 242
240 std::thread render_thread([&emu_window] { emu_window->Present(); }); 243 std::thread render_thread([&emu_window] { emu_window->Present(); });
241 system.Run(); 244 system.Run();
diff --git a/src/yuzu_tester/yuzu.cpp b/src/yuzu_tester/yuzu.cpp
index 7acf0caad..5798ce43a 100644
--- a/src/yuzu_tester/yuzu.cpp
+++ b/src/yuzu_tester/yuzu.cpp
@@ -255,7 +255,6 @@ int main(int argc, char** argv) {
255 "SDLHideTester"); 255 "SDLHideTester");
256 256
257 system.GPU().Start(); 257 system.GPU().Start();
258 system.Renderer().Rasterizer().LoadDiskResources();
259 258
260 system.Run(); 259 system.Run();
261 while (!finished) { 260 while (!finished) {