summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-02-20 20:35:53 -0300
committerGravatar ReinUsesLisp2020-02-28 17:56:43 -0300
commit1bd95a314f07732319a71fca2aba81d400ca4c83 (patch)
treed524ce30dbcf56e26d3b0d93c07aa1715e372779 /src
parentgl_rasterizer: Remove num vertex buffers magic number (diff)
downloadyuzu-1bd95a314f07732319a71fca2aba81d400ca4c83.tar.gz
yuzu-1bd95a314f07732319a71fca2aba81d400ca4c83.tar.xz
yuzu-1bd95a314f07732319a71fca2aba81d400ca4c83.zip
vk_state_tracker: Initial implementation
Add support for render targets and viewports.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp8
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp17
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h5
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.cpp21
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.h42
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp97
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h53
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp1
10 files changed, 198 insertions, 52 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 18b774ac7..06c174a5b 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -199,6 +199,8 @@ if (ENABLE_VULKAN)
199 renderer_vulkan/vk_shader_util.h 199 renderer_vulkan/vk_shader_util.h
200 renderer_vulkan/vk_staging_buffer_pool.cpp 200 renderer_vulkan/vk_staging_buffer_pool.cpp
201 renderer_vulkan/vk_staging_buffer_pool.h 201 renderer_vulkan/vk_staging_buffer_pool.h
202 renderer_vulkan/vk_state_tracker.cpp
203 renderer_vulkan/vk_state_tracker.h
202 renderer_vulkan/vk_stream_buffer.cpp 204 renderer_vulkan/vk_stream_buffer.cpp
203 renderer_vulkan/vk_stream_buffer.h 205 renderer_vulkan/vk_stream_buffer.h
204 renderer_vulkan/vk_swapchain.cpp 206 renderer_vulkan/vk_swapchain.cpp
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index ddc62bc97..42bb01418 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -27,6 +27,7 @@
27#include "video_core/renderer_vulkan/vk_rasterizer.h" 27#include "video_core/renderer_vulkan/vk_rasterizer.h"
28#include "video_core/renderer_vulkan/vk_resource_manager.h" 28#include "video_core/renderer_vulkan/vk_resource_manager.h"
29#include "video_core/renderer_vulkan/vk_scheduler.h" 29#include "video_core/renderer_vulkan/vk_scheduler.h"
30#include "video_core/renderer_vulkan/vk_state_tracker.h"
30#include "video_core/renderer_vulkan/vk_swapchain.h" 31#include "video_core/renderer_vulkan/vk_swapchain.h"
31 32
32namespace Vulkan { 33namespace Vulkan {
@@ -177,10 +178,13 @@ bool RendererVulkan::Init() {
177 swapchain = std::make_unique<VKSwapchain>(surface, *device); 178 swapchain = std::make_unique<VKSwapchain>(surface, *device);
178 swapchain->Create(framebuffer.width, framebuffer.height, false); 179 swapchain->Create(framebuffer.width, framebuffer.height, false);
179 180
180 scheduler = std::make_unique<VKScheduler>(*device, *resource_manager); 181 state_tracker = std::make_unique<StateTracker>(system);
182
183 scheduler = std::make_unique<VKScheduler>(*device, *resource_manager, *state_tracker);
181 184
182 rasterizer = std::make_unique<RasterizerVulkan>(system, render_window, screen_info, *device, 185 rasterizer = std::make_unique<RasterizerVulkan>(system, render_window, screen_info, *device,
183 *resource_manager, *memory_manager, *scheduler); 186 *resource_manager, *memory_manager,
187 *state_tracker, *scheduler);
184 188
185 blit_screen = std::make_unique<VKBlitScreen>(system, render_window, *rasterizer, *device, 189 blit_screen = std::make_unique<VKBlitScreen>(system, render_window, *rasterizer, *device,
186 *resource_manager, *memory_manager, *swapchain, 190 *resource_manager, *memory_manager, *swapchain,
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h
index f513397f0..3da08d2e4 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.h
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.h
@@ -4,8 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include <optional> 8#include <optional>
8#include <vector> 9#include <vector>
10
9#include "video_core/renderer_base.h" 11#include "video_core/renderer_base.h"
10#include "video_core/renderer_vulkan/declarations.h" 12#include "video_core/renderer_vulkan/declarations.h"
11 13
@@ -15,6 +17,7 @@ class System;
15 17
16namespace Vulkan { 18namespace Vulkan {
17 19
20class StateTracker;
18class VKBlitScreen; 21class VKBlitScreen;
19class VKDevice; 22class VKDevice;
20class VKFence; 23class VKFence;
@@ -61,6 +64,7 @@ private:
61 std::unique_ptr<VKSwapchain> swapchain; 64 std::unique_ptr<VKSwapchain> swapchain;
62 std::unique_ptr<VKMemoryManager> memory_manager; 65 std::unique_ptr<VKMemoryManager> memory_manager;
63 std::unique_ptr<VKResourceManager> resource_manager; 66 std::unique_ptr<VKResourceManager> resource_manager;
67 std::unique_ptr<StateTracker> state_tracker;
64 std::unique_ptr<VKScheduler> scheduler; 68 std::unique_ptr<VKScheduler> scheduler;
65 std::unique_ptr<VKBlitScreen> blit_screen; 69 std::unique_ptr<VKBlitScreen> blit_screen;
66}; 70};
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index b1be41a21..41cbf4134 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -36,6 +36,7 @@
36#include "video_core/renderer_vulkan/vk_sampler_cache.h" 36#include "video_core/renderer_vulkan/vk_sampler_cache.h"
37#include "video_core/renderer_vulkan/vk_scheduler.h" 37#include "video_core/renderer_vulkan/vk_scheduler.h"
38#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" 38#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
39#include "video_core/renderer_vulkan/vk_state_tracker.h"
39#include "video_core/renderer_vulkan/vk_texture_cache.h" 40#include "video_core/renderer_vulkan/vk_texture_cache.h"
40#include "video_core/renderer_vulkan/vk_update_descriptor.h" 41#include "video_core/renderer_vulkan/vk_update_descriptor.h"
41 42
@@ -277,10 +278,11 @@ void RasterizerVulkan::DrawParameters::Draw(vk::CommandBuffer cmdbuf,
277RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer, 278RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer,
278 VKScreenInfo& screen_info, const VKDevice& device, 279 VKScreenInfo& screen_info, const VKDevice& device,
279 VKResourceManager& resource_manager, 280 VKResourceManager& resource_manager,
280 VKMemoryManager& memory_manager, VKScheduler& scheduler) 281 VKMemoryManager& memory_manager, StateTracker& state_tracker,
282 VKScheduler& scheduler)
281 : RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer}, 283 : RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer},
282 screen_info{screen_info}, device{device}, resource_manager{resource_manager}, 284 screen_info{screen_info}, device{device}, resource_manager{resource_manager},
283 memory_manager{memory_manager}, scheduler{scheduler}, 285 memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler},
284 staging_pool(device, memory_manager, scheduler), descriptor_pool(device), 286 staging_pool(device, memory_manager, scheduler), descriptor_pool(device),
285 update_descriptor_queue(device, scheduler), 287 update_descriptor_queue(device, scheduler),
286 quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), 288 quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
@@ -545,6 +547,10 @@ bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config,
545 return true; 547 return true;
546} 548}
547 549
550void RasterizerVulkan::SetupDirtyFlags() {
551 state_tracker.Initialize();
552}
553
548void RasterizerVulkan::FlushWork() { 554void RasterizerVulkan::FlushWork() {
549 static constexpr u32 DRAWS_TO_DISPATCH = 4096; 555 static constexpr u32 DRAWS_TO_DISPATCH = 4096;
550 556
@@ -568,7 +574,9 @@ void RasterizerVulkan::FlushWork() {
568 574
569RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { 575RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() {
570 MICROPROFILE_SCOPE(Vulkan_RenderTargets); 576 MICROPROFILE_SCOPE(Vulkan_RenderTargets);
571 constexpr bool update_rendertargets = true; 577 auto& dirty = system.GPU().Maxwell3D().dirty.flags;
578 const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets];
579 dirty[VideoCommon::Dirty::RenderTargets] = false;
572 580
573 texture_cache.GuardRenderTargets(true); 581 texture_cache.GuardRenderTargets(true);
574 582
@@ -971,6 +979,9 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima
971} 979}
972 980
973void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { 981void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) {
982 if (!state_tracker.TouchViewports()) {
983 return;
984 }
974 const auto& regs = gpu.regs; 985 const auto& regs = gpu.regs;
975 const std::array viewports{ 986 const std::array viewports{
976 GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), 987 GetViewportState(device, regs, 0), GetViewportState(device, regs, 1),
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 4dc8af6e8..a79440eba 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -96,6 +96,7 @@ struct hash<Vulkan::FramebufferCacheKey> {
96 96
97namespace Vulkan { 97namespace Vulkan {
98 98
99class StateTracker;
99class BufferBindings; 100class BufferBindings;
100 101
101struct ImageView { 102struct ImageView {
@@ -108,7 +109,7 @@ public:
108 explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window, 109 explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window,
109 VKScreenInfo& screen_info, const VKDevice& device, 110 VKScreenInfo& screen_info, const VKDevice& device,
110 VKResourceManager& resource_manager, VKMemoryManager& memory_manager, 111 VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
111 VKScheduler& scheduler); 112 StateTracker& state_tracker, VKScheduler& scheduler);
112 ~RasterizerVulkan() override; 113 ~RasterizerVulkan() override;
113 114
114 void Draw(bool is_indexed, bool is_instanced) override; 115 void Draw(bool is_indexed, bool is_instanced) override;
@@ -127,6 +128,7 @@ public:
127 const Tegra::Engines::Fermi2D::Config& copy_config) override; 128 const Tegra::Engines::Fermi2D::Config& copy_config) override;
128 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, 129 bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
129 u32 pixel_stride) override; 130 u32 pixel_stride) override;
131 void SetupDirtyFlags() override;
130 132
131 /// Maximum supported size that a constbuffer can have in bytes. 133 /// Maximum supported size that a constbuffer can have in bytes.
132 static constexpr std::size_t MaxConstbufferSize = 0x10000; 134 static constexpr std::size_t MaxConstbufferSize = 0x10000;
@@ -241,6 +243,7 @@ private:
241 const VKDevice& device; 243 const VKDevice& device;
242 VKResourceManager& resource_manager; 244 VKResourceManager& resource_manager;
243 VKMemoryManager& memory_manager; 245 VKMemoryManager& memory_manager;
246 StateTracker& state_tracker;
244 VKScheduler& scheduler; 247 VKScheduler& scheduler;
245 248
246 VKStagingBufferPool staging_pool; 249 VKStagingBufferPool staging_pool;
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp
index 92bd6c344..b61d4fe63 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.cpp
+++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp
@@ -2,6 +2,12 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <memory>
6#include <mutex>
7#include <optional>
8#include <thread>
9#include <utility>
10
5#include "common/assert.h" 11#include "common/assert.h"
6#include "common/microprofile.h" 12#include "common/microprofile.h"
7#include "video_core/renderer_vulkan/declarations.h" 13#include "video_core/renderer_vulkan/declarations.h"
@@ -9,6 +15,7 @@
9#include "video_core/renderer_vulkan/vk_query_cache.h" 15#include "video_core/renderer_vulkan/vk_query_cache.h"
10#include "video_core/renderer_vulkan/vk_resource_manager.h" 16#include "video_core/renderer_vulkan/vk_resource_manager.h"
11#include "video_core/renderer_vulkan/vk_scheduler.h" 17#include "video_core/renderer_vulkan/vk_scheduler.h"
18#include "video_core/renderer_vulkan/vk_state_tracker.h"
12 19
13namespace Vulkan { 20namespace Vulkan {
14 21
@@ -29,9 +36,10 @@ void VKScheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf,
29 last = nullptr; 36 last = nullptr;
30} 37}
31 38
32VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager) 39VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager,
33 : device{device}, resource_manager{resource_manager}, next_fence{ 40 StateTracker& state_tracker)
34 &resource_manager.CommitFence()} { 41 : device{device}, resource_manager{resource_manager}, state_tracker{state_tracker},
42 next_fence{&resource_manager.CommitFence()} {
35 AcquireNewChunk(); 43 AcquireNewChunk();
36 AllocateNewContext(); 44 AllocateNewContext();
37 worker_thread = std::thread(&VKScheduler::WorkerThread, this); 45 worker_thread = std::thread(&VKScheduler::WorkerThread, this);
@@ -157,12 +165,7 @@ void VKScheduler::AllocateNewContext() {
157 165
158void VKScheduler::InvalidateState() { 166void VKScheduler::InvalidateState() {
159 state.graphics_pipeline = nullptr; 167 state.graphics_pipeline = nullptr;
160 state.viewports = false; 168 state_tracker.InvalidateCommandBufferState();
161 state.scissors = false;
162 state.depth_bias = false;
163 state.blend_constants = false;
164 state.depth_bounds = false;
165 state.stencil_values = false;
166} 169}
167 170
168void VKScheduler::EndPendingOperations() { 171void VKScheduler::EndPendingOperations() {
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h
index 62fd7858b..c7cc291c3 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.h
+++ b/src/video_core/renderer_vulkan/vk_scheduler.h
@@ -17,6 +17,7 @@
17 17
18namespace Vulkan { 18namespace Vulkan {
19 19
20class StateTracker;
20class VKDevice; 21class VKDevice;
21class VKFence; 22class VKFence;
22class VKQueryCache; 23class VKQueryCache;
@@ -43,7 +44,8 @@ private:
43/// OpenGL-like operations on Vulkan command buffers. 44/// OpenGL-like operations on Vulkan command buffers.
44class VKScheduler { 45class VKScheduler {
45public: 46public:
46 explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager); 47 explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager,
48 StateTracker& state_tracker);
47 ~VKScheduler(); 49 ~VKScheduler();
48 50
49 /// Sends the current execution context to the GPU. 51 /// Sends the current execution context to the GPU.
@@ -74,36 +76,6 @@ public:
74 query_cache = &query_cache_; 76 query_cache = &query_cache_;
75 } 77 }
76 78
77 /// Returns true when viewports have been set in the current command buffer.
78 bool TouchViewports() {
79 return std::exchange(state.viewports, true);
80 }
81
82 /// Returns true when scissors have been set in the current command buffer.
83 bool TouchScissors() {
84 return std::exchange(state.scissors, true);
85 }
86
87 /// Returns true when depth bias have been set in the current command buffer.
88 bool TouchDepthBias() {
89 return std::exchange(state.depth_bias, true);
90 }
91
92 /// Returns true when blend constants have been set in the current command buffer.
93 bool TouchBlendConstants() {
94 return std::exchange(state.blend_constants, true);
95 }
96
97 /// Returns true when depth bounds have been set in the current command buffer.
98 bool TouchDepthBounds() {
99 return std::exchange(state.depth_bounds, true);
100 }
101
102 /// Returns true when stencil values have been set in the current command buffer.
103 bool TouchStencilValues() {
104 return std::exchange(state.stencil_values, true);
105 }
106
107 /// Send work to a separate thread. 79 /// Send work to a separate thread.
108 template <typename T> 80 template <typename T>
109 void Record(T&& command) { 81 void Record(T&& command) {
@@ -217,6 +189,8 @@ private:
217 189
218 const VKDevice& device; 190 const VKDevice& device;
219 VKResourceManager& resource_manager; 191 VKResourceManager& resource_manager;
192 StateTracker& state_tracker;
193
220 VKQueryCache* query_cache = nullptr; 194 VKQueryCache* query_cache = nullptr;
221 195
222 vk::CommandBuffer current_cmdbuf; 196 vk::CommandBuffer current_cmdbuf;
@@ -226,12 +200,6 @@ private:
226 struct State { 200 struct State {
227 std::optional<vk::RenderPassBeginInfo> renderpass; 201 std::optional<vk::RenderPassBeginInfo> renderpass;
228 vk::Pipeline graphics_pipeline; 202 vk::Pipeline graphics_pipeline;
229 bool viewports = false;
230 bool scissors = false;
231 bool depth_bias = false;
232 bool blend_constants = false;
233 bool depth_bounds = false;
234 bool stencil_values = false;
235 } state; 203 } state;
236 204
237 std::unique_ptr<CommandChunk> chunk; 205 std::unique_ptr<CommandChunk> chunk;
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
new file mode 100644
index 000000000..d44992dc9
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -0,0 +1,97 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <type_traits>
6
7#include "common/common_types.h"
8#include "core/core.h"
9#include "video_core/engines/maxwell_3d.h"
10#include "video_core/gpu.h"
11#include "video_core/renderer_vulkan/vk_state_tracker.h"
12
13#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name)
14#define NUM(field_name) (sizeof(Maxwell3D::Regs::field_name) / sizeof(u32))
15
16namespace Vulkan {
17
18namespace {
19
20using namespace Dirty;
21using namespace VideoCommon::Dirty;
22using Tegra::Engines::Maxwell3D;
23using Regs = Maxwell3D::Regs;
24using Dirty = std::remove_reference_t<decltype(Maxwell3D::dirty)>;
25using Tables = std::remove_reference_t<decltype(Maxwell3D::dirty.tables)>;
26using Table = std::remove_reference_t<decltype(Maxwell3D::dirty.tables[0])>;
27using Flags = std::remove_reference_t<decltype(Maxwell3D::dirty.flags)>;
28
29Flags MakeInvalidationFlags() {
30 Flags flags{};
31 flags[Viewports] = true;
32 return flags;
33}
34
35template <typename Integer>
36void FillBlock(Table& table, std::size_t begin, std::size_t num, Integer dirty_index) {
37 const auto it = std::begin(table) + begin;
38 std::fill(it, it + num, static_cast<u8>(dirty_index));
39}
40
41template <typename Integer1, typename Integer2>
42void FillBlock(Tables& tables, std::size_t begin, std::size_t num, Integer1 index_a,
43 Integer2 index_b) {
44 FillBlock(tables[0], begin, num, index_a);
45 FillBlock(tables[1], begin, num, index_b);
46}
47
48void SetupDirtyRenderTargets(Tables& tables) {
49 static constexpr std::size_t num_per_rt = NUM(rt[0]);
50 static constexpr std::size_t begin = OFF(rt);
51 static constexpr std::size_t num = num_per_rt * Regs::NumRenderTargets;
52 for (std::size_t rt = 0; rt < Regs::NumRenderTargets; ++rt) {
53 FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt);
54 }
55 FillBlock(tables[1], begin, num, RenderTargets);
56
57 static constexpr std::array zeta_flags{ZetaBuffer, RenderTargets};
58 for (std::size_t i = 0; i < std::size(zeta_flags); ++i) {
59 const u8 flag = zeta_flags[i];
60 auto& table = tables[i];
61 table[OFF(zeta_enable)] = flag;
62 table[OFF(zeta_width)] = flag;
63 table[OFF(zeta_height)] = flag;
64 FillBlock(table, OFF(zeta), NUM(zeta), flag);
65 }
66}
67
68void SetupDirtyViewports(Tables& tables) {
69 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
70 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
71 tables[0][OFF(viewport_transform_enabled)] = Viewports;
72}
73
74} // Anonymous namespace
75
76StateTracker::StateTracker(Core::System& system)
77 : system{system}, invalidation_flags{MakeInvalidationFlags()} {}
78
79void StateTracker::Initialize() {
80 auto& dirty = system.GPU().Maxwell3D().dirty;
81 auto& tables = dirty.tables;
82 SetupDirtyRenderTargets(tables);
83 SetupDirtyViewports(tables);
84
85 auto& store = dirty.on_write_stores;
86 store[RenderTargets] = true;
87 store[ZetaBuffer] = true;
88 for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
89 store[ColorBuffer0 + i] = true;
90 }
91}
92
93void StateTracker::InvalidateCommandBufferState() {
94 system.GPU().Maxwell3D().dirty.flags |= invalidation_flags;
95}
96
97} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h
new file mode 100644
index 000000000..9ec7b5136
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.h
@@ -0,0 +1,53 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <type_traits> // REMOVE ME
8#include <utility>
9
10#include "common/common_types.h"
11#include "core/core.h"
12#include "video_core/dirty_flags.h"
13#include "video_core/engines/maxwell_3d.h"
14
15namespace Vulkan {
16
17namespace Dirty {
18
19enum : u8 {
20 First = VideoCommon::Dirty::LastCommonEntry,
21
22 Viewports,
23};
24
25} // namespace Dirty
26
27class StateTracker {
28public:
29 explicit StateTracker(Core::System& system);
30
31 void Initialize();
32
33 void InvalidateCommandBufferState();
34
35 bool TouchViewports() {
36 return Exchange(Dirty::Viewports, false);
37 }
38
39private:
40 using Flags = std::remove_reference_t<decltype(Tegra::Engines::Maxwell3D::dirty.flags)>;
41
42 bool Exchange(std::size_t id, bool new_value) const noexcept {
43 auto& flags = system.GPU().Maxwell3D().dirty.flags;
44 const bool is_dirty = flags[id];
45 flags[id] = new_value;
46 return is_dirty;
47 }
48
49 Core::System& system;
50 Flags invalidation_flags;
51};
52
53} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 51b0d38a6..73d92a5ae 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -22,6 +22,7 @@
22#include "video_core/renderer_vulkan/vk_device.h" 22#include "video_core/renderer_vulkan/vk_device.h"
23#include "video_core/renderer_vulkan/vk_memory_manager.h" 23#include "video_core/renderer_vulkan/vk_memory_manager.h"
24#include "video_core/renderer_vulkan/vk_rasterizer.h" 24#include "video_core/renderer_vulkan/vk_rasterizer.h"
25#include "video_core/renderer_vulkan/vk_scheduler.h"
25#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" 26#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
26#include "video_core/renderer_vulkan/vk_texture_cache.h" 27#include "video_core/renderer_vulkan/vk_texture_cache.h"
27#include "video_core/surface.h" 28#include "video_core/surface.h"