diff options
| author | 2020-02-20 20:35:53 -0300 | |
|---|---|---|
| committer | 2020-02-28 17:56:43 -0300 | |
| commit | 1bd95a314f07732319a71fca2aba81d400ca4c83 (patch) | |
| tree | d524ce30dbcf56e26d3b0d93c07aa1715e372779 /src | |
| parent | gl_rasterizer: Remove num vertex buffers magic number (diff) | |
| download | yuzu-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.txt | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_scheduler.cpp | 21 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_scheduler.h | 42 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.cpp | 97 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.h | 53 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 1 |
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 | ||
| 32 | namespace Vulkan { | 33 | namespace 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 | ||
| 16 | namespace Vulkan { | 18 | namespace Vulkan { |
| 17 | 19 | ||
| 20 | class StateTracker; | ||
| 18 | class VKBlitScreen; | 21 | class VKBlitScreen; |
| 19 | class VKDevice; | 22 | class VKDevice; |
| 20 | class VKFence; | 23 | class 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, | |||
| 277 | RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer, | 278 | RasterizerVulkan::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 | ||
| 550 | void RasterizerVulkan::SetupDirtyFlags() { | ||
| 551 | state_tracker.Initialize(); | ||
| 552 | } | ||
| 553 | |||
| 548 | void RasterizerVulkan::FlushWork() { | 554 | void 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 | ||
| 569 | RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { | 575 | RasterizerVulkan::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 | ||
| 973 | void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { | 981 | void 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 | ||
| 97 | namespace Vulkan { | 97 | namespace Vulkan { |
| 98 | 98 | ||
| 99 | class StateTracker; | ||
| 99 | class BufferBindings; | 100 | class BufferBindings; |
| 100 | 101 | ||
| 101 | struct ImageView { | 102 | struct 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 | ||
| 13 | namespace Vulkan { | 20 | namespace Vulkan { |
| 14 | 21 | ||
| @@ -29,9 +36,10 @@ void VKScheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf, | |||
| 29 | last = nullptr; | 36 | last = nullptr; |
| 30 | } | 37 | } |
| 31 | 38 | ||
| 32 | VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager) | 39 | VKScheduler::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 | ||
| 158 | void VKScheduler::InvalidateState() { | 166 | void 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 | ||
| 168 | void VKScheduler::EndPendingOperations() { | 171 | void 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 | ||
| 18 | namespace Vulkan { | 18 | namespace Vulkan { |
| 19 | 19 | ||
| 20 | class StateTracker; | ||
| 20 | class VKDevice; | 21 | class VKDevice; |
| 21 | class VKFence; | 22 | class VKFence; |
| 22 | class VKQueryCache; | 23 | class VKQueryCache; |
| @@ -43,7 +44,8 @@ private: | |||
| 43 | /// OpenGL-like operations on Vulkan command buffers. | 44 | /// OpenGL-like operations on Vulkan command buffers. |
| 44 | class VKScheduler { | 45 | class VKScheduler { |
| 45 | public: | 46 | public: |
| 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 | |||
| 16 | namespace Vulkan { | ||
| 17 | |||
| 18 | namespace { | ||
| 19 | |||
| 20 | using namespace Dirty; | ||
| 21 | using namespace VideoCommon::Dirty; | ||
| 22 | using Tegra::Engines::Maxwell3D; | ||
| 23 | using Regs = Maxwell3D::Regs; | ||
| 24 | using Dirty = std::remove_reference_t<decltype(Maxwell3D::dirty)>; | ||
| 25 | using Tables = std::remove_reference_t<decltype(Maxwell3D::dirty.tables)>; | ||
| 26 | using Table = std::remove_reference_t<decltype(Maxwell3D::dirty.tables[0])>; | ||
| 27 | using Flags = std::remove_reference_t<decltype(Maxwell3D::dirty.flags)>; | ||
| 28 | |||
| 29 | Flags MakeInvalidationFlags() { | ||
| 30 | Flags flags{}; | ||
| 31 | flags[Viewports] = true; | ||
| 32 | return flags; | ||
| 33 | } | ||
| 34 | |||
| 35 | template <typename Integer> | ||
| 36 | void 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 | |||
| 41 | template <typename Integer1, typename Integer2> | ||
| 42 | void 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 | |||
| 48 | void 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 | |||
| 68 | void 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 | |||
| 76 | StateTracker::StateTracker(Core::System& system) | ||
| 77 | : system{system}, invalidation_flags{MakeInvalidationFlags()} {} | ||
| 78 | |||
| 79 | void 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 | |||
| 93 | void 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 | |||
| 15 | namespace Vulkan { | ||
| 16 | |||
| 17 | namespace Dirty { | ||
| 18 | |||
| 19 | enum : u8 { | ||
| 20 | First = VideoCommon::Dirty::LastCommonEntry, | ||
| 21 | |||
| 22 | Viewports, | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Dirty | ||
| 26 | |||
| 27 | class StateTracker { | ||
| 28 | public: | ||
| 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 | |||
| 39 | private: | ||
| 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" |