diff options
| author | 2020-03-09 18:34:37 -0300 | |
|---|---|---|
| committer | 2020-03-09 18:34:37 -0300 | |
| commit | 22e825a3bc0d9bfb5f8c29a50724c2887014dc02 (patch) | |
| tree | d68f0ace93ba44292e3017dcb219f3132b3314ef /src/video_core/renderer_vulkan | |
| parent | Merge pull request #3486 from ReinUsesLisp/fix-anisotropy-hack (diff) | |
| parent | video_core/dirty_flags: Address feedback (diff) | |
| download | yuzu-22e825a3bc0d9bfb5f8c29a50724c2887014dc02.tar.gz yuzu-22e825a3bc0d9bfb5f8c29a50724c2887014dc02.tar.xz yuzu-22e825a3bc0d9bfb5f8c29a50724c2887014dc02.zip | |
Merge pull request #3301 from ReinUsesLisp/state-tracker
video_core: Remove gl_state and use a state tracker based on dirty flags
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/fixed_pipeline_state.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.h | 4 | ||||
| -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_pipeline_cache.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 69 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 17 | ||||
| -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 | 101 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.h | 79 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 1 |
14 files changed, 270 insertions, 118 deletions
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 4e3ff231e..2bb376555 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | |||
| @@ -112,19 +112,18 @@ constexpr FixedPipelineState::Rasterizer GetRasterizerState(const Maxwell& regs) | |||
| 112 | const auto& clip = regs.view_volume_clip_control; | 112 | const auto& clip = regs.view_volume_clip_control; |
| 113 | const bool depth_clamp_enabled = clip.depth_clamp_near == 1 || clip.depth_clamp_far == 1; | 113 | const bool depth_clamp_enabled = clip.depth_clamp_near == 1 || clip.depth_clamp_far == 1; |
| 114 | 114 | ||
| 115 | Maxwell::Cull::FrontFace front_face = regs.cull.front_face; | 115 | Maxwell::FrontFace front_face = regs.front_face; |
| 116 | if (regs.screen_y_control.triangle_rast_flip != 0 && | 116 | if (regs.screen_y_control.triangle_rast_flip != 0 && |
| 117 | regs.viewport_transform[0].scale_y > 0.0f) { | 117 | regs.viewport_transform[0].scale_y > 0.0f) { |
| 118 | if (front_face == Maxwell::Cull::FrontFace::CounterClockWise) | 118 | if (front_face == Maxwell::FrontFace::CounterClockWise) |
| 119 | front_face = Maxwell::Cull::FrontFace::ClockWise; | 119 | front_face = Maxwell::FrontFace::ClockWise; |
| 120 | else if (front_face == Maxwell::Cull::FrontFace::ClockWise) | 120 | else if (front_face == Maxwell::FrontFace::ClockWise) |
| 121 | front_face = Maxwell::Cull::FrontFace::CounterClockWise; | 121 | front_face = Maxwell::FrontFace::CounterClockWise; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | const bool gl_ndc = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; | 124 | const bool gl_ndc = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; |
| 125 | return FixedPipelineState::Rasterizer(regs.cull.enabled, depth_bias_enabled, | 125 | return FixedPipelineState::Rasterizer(regs.cull_test_enabled, depth_bias_enabled, |
| 126 | depth_clamp_enabled, gl_ndc, regs.cull.cull_face, | 126 | depth_clamp_enabled, gl_ndc, regs.cull_face, front_face); |
| 127 | front_face); | ||
| 128 | } | 127 | } |
| 129 | 128 | ||
| 130 | } // Anonymous namespace | 129 | } // Anonymous namespace |
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h index 87056ef37..4c8ba7f90 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h | |||
| @@ -171,8 +171,8 @@ struct FixedPipelineState { | |||
| 171 | 171 | ||
| 172 | struct Rasterizer { | 172 | struct Rasterizer { |
| 173 | constexpr Rasterizer(bool cull_enable, bool depth_bias_enable, bool depth_clamp_enable, | 173 | constexpr Rasterizer(bool cull_enable, bool depth_bias_enable, bool depth_clamp_enable, |
| 174 | bool ndc_minus_one_to_one, Maxwell::Cull::CullFace cull_face, | 174 | bool ndc_minus_one_to_one, Maxwell::CullFace cull_face, |
| 175 | Maxwell::Cull::FrontFace front_face) | 175 | Maxwell::FrontFace front_face) |
| 176 | : cull_enable{cull_enable}, depth_bias_enable{depth_bias_enable}, | 176 | : cull_enable{cull_enable}, depth_bias_enable{depth_bias_enable}, |
| 177 | depth_clamp_enable{depth_clamp_enable}, ndc_minus_one_to_one{ndc_minus_one_to_one}, | 177 | depth_clamp_enable{depth_clamp_enable}, ndc_minus_one_to_one{ndc_minus_one_to_one}, |
| 178 | cull_face{cull_face}, front_face{front_face} {} | 178 | cull_face{cull_face}, front_face{front_face} {} |
| @@ -182,8 +182,8 @@ struct FixedPipelineState { | |||
| 182 | bool depth_bias_enable; | 182 | bool depth_bias_enable; |
| 183 | bool depth_clamp_enable; | 183 | bool depth_clamp_enable; |
| 184 | bool ndc_minus_one_to_one; | 184 | bool ndc_minus_one_to_one; |
| 185 | Maxwell::Cull::CullFace cull_face; | 185 | Maxwell::CullFace cull_face; |
| 186 | Maxwell::Cull::FrontFace front_face; | 186 | Maxwell::FrontFace front_face; |
| 187 | 187 | ||
| 188 | std::size_t Hash() const noexcept; | 188 | std::size_t Hash() const noexcept; |
| 189 | 189 | ||
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 948d67d89..df3ac707c 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -586,24 +586,24 @@ vk::BlendFactor BlendFactor(Maxwell::Blend::Factor factor) { | |||
| 586 | return {}; | 586 | return {}; |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | vk::FrontFace FrontFace(Maxwell::Cull::FrontFace front_face) { | 589 | vk::FrontFace FrontFace(Maxwell::FrontFace front_face) { |
| 590 | switch (front_face) { | 590 | switch (front_face) { |
| 591 | case Maxwell::Cull::FrontFace::ClockWise: | 591 | case Maxwell::FrontFace::ClockWise: |
| 592 | return vk::FrontFace::eClockwise; | 592 | return vk::FrontFace::eClockwise; |
| 593 | case Maxwell::Cull::FrontFace::CounterClockWise: | 593 | case Maxwell::FrontFace::CounterClockWise: |
| 594 | return vk::FrontFace::eCounterClockwise; | 594 | return vk::FrontFace::eCounterClockwise; |
| 595 | } | 595 | } |
| 596 | UNIMPLEMENTED_MSG("Unimplemented front face={}", static_cast<u32>(front_face)); | 596 | UNIMPLEMENTED_MSG("Unimplemented front face={}", static_cast<u32>(front_face)); |
| 597 | return {}; | 597 | return {}; |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | vk::CullModeFlags CullFace(Maxwell::Cull::CullFace cull_face) { | 600 | vk::CullModeFlags CullFace(Maxwell::CullFace cull_face) { |
| 601 | switch (cull_face) { | 601 | switch (cull_face) { |
| 602 | case Maxwell::Cull::CullFace::Front: | 602 | case Maxwell::CullFace::Front: |
| 603 | return vk::CullModeFlagBits::eFront; | 603 | return vk::CullModeFlagBits::eFront; |
| 604 | case Maxwell::Cull::CullFace::Back: | 604 | case Maxwell::CullFace::Back: |
| 605 | return vk::CullModeFlagBits::eBack; | 605 | return vk::CullModeFlagBits::eBack; |
| 606 | case Maxwell::Cull::CullFace::FrontAndBack: | 606 | case Maxwell::CullFace::FrontAndBack: |
| 607 | return vk::CullModeFlagBits::eFrontAndBack; | 607 | return vk::CullModeFlagBits::eFrontAndBack; |
| 608 | } | 608 | } |
| 609 | UNIMPLEMENTED_MSG("Unimplemented cull face={}", static_cast<u32>(cull_face)); | 609 | UNIMPLEMENTED_MSG("Unimplemented cull face={}", static_cast<u32>(cull_face)); |
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h index 7e9678b7b..24f6ab544 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.h +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h | |||
| @@ -54,9 +54,9 @@ vk::BlendOp BlendEquation(Maxwell::Blend::Equation equation); | |||
| 54 | 54 | ||
| 55 | vk::BlendFactor BlendFactor(Maxwell::Blend::Factor factor); | 55 | vk::BlendFactor BlendFactor(Maxwell::Blend::Factor factor); |
| 56 | 56 | ||
| 57 | vk::FrontFace FrontFace(Maxwell::Cull::FrontFace front_face); | 57 | vk::FrontFace FrontFace(Maxwell::FrontFace front_face); |
| 58 | 58 | ||
| 59 | vk::CullModeFlags CullFace(Maxwell::Cull::CullFace cull_face); | 59 | vk::CullModeFlags CullFace(Maxwell::CullFace cull_face); |
| 60 | 60 | ||
| 61 | vk::ComponentSwizzle SwizzleSource(Tegra::Texture::SwizzleSource swizzle); | 61 | vk::ComponentSwizzle SwizzleSource(Tegra::Texture::SwizzleSource swizzle); |
| 62 | 62 | ||
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_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 696e4b291..144e1e007 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -188,11 +188,6 @@ VKPipelineCache::~VKPipelineCache() = default; | |||
| 188 | 188 | ||
| 189 | std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { | 189 | std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { |
| 190 | const auto& gpu = system.GPU().Maxwell3D(); | 190 | const auto& gpu = system.GPU().Maxwell3D(); |
| 191 | auto& dirty = system.GPU().Maxwell3D().dirty.shaders; | ||
| 192 | if (!dirty) { | ||
| 193 | return last_shaders; | ||
| 194 | } | ||
| 195 | dirty = false; | ||
| 196 | 191 | ||
| 197 | std::array<Shader, Maxwell::MaxShaderProgram> shaders; | 192 | std::array<Shader, Maxwell::MaxShaderProgram> shaders; |
| 198 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 193 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 3fe28c204..b402fb268 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 | ||
| @@ -280,10 +281,11 @@ void RasterizerVulkan::DrawParameters::Draw(vk::CommandBuffer cmdbuf, | |||
| 280 | RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer, | 281 | RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer, |
| 281 | VKScreenInfo& screen_info, const VKDevice& device, | 282 | VKScreenInfo& screen_info, const VKDevice& device, |
| 282 | VKResourceManager& resource_manager, | 283 | VKResourceManager& resource_manager, |
| 283 | VKMemoryManager& memory_manager, VKScheduler& scheduler) | 284 | VKMemoryManager& memory_manager, StateTracker& state_tracker, |
| 285 | VKScheduler& scheduler) | ||
| 284 | : RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer}, | 286 | : RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer}, |
| 285 | screen_info{screen_info}, device{device}, resource_manager{resource_manager}, | 287 | screen_info{screen_info}, device{device}, resource_manager{resource_manager}, |
| 286 | memory_manager{memory_manager}, scheduler{scheduler}, | 288 | memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler}, |
| 287 | staging_pool(device, memory_manager, scheduler), descriptor_pool(device), | 289 | staging_pool(device, memory_manager, scheduler), descriptor_pool(device), |
| 288 | update_descriptor_queue(device, scheduler), | 290 | update_descriptor_queue(device, scheduler), |
| 289 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 291 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| @@ -548,6 +550,10 @@ bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, | |||
| 548 | return true; | 550 | return true; |
| 549 | } | 551 | } |
| 550 | 552 | ||
| 553 | void RasterizerVulkan::SetupDirtyFlags() { | ||
| 554 | state_tracker.Initialize(); | ||
| 555 | } | ||
| 556 | |||
| 551 | void RasterizerVulkan::FlushWork() { | 557 | void RasterizerVulkan::FlushWork() { |
| 552 | static constexpr u32 DRAWS_TO_DISPATCH = 4096; | 558 | static constexpr u32 DRAWS_TO_DISPATCH = 4096; |
| 553 | 559 | ||
| @@ -571,9 +577,9 @@ void RasterizerVulkan::FlushWork() { | |||
| 571 | 577 | ||
| 572 | RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { | 578 | RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { |
| 573 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); | 579 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); |
| 574 | auto& dirty = system.GPU().Maxwell3D().dirty; | 580 | auto& dirty = system.GPU().Maxwell3D().dirty.flags; |
| 575 | const bool update_rendertargets = dirty.render_settings; | 581 | const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets]; |
| 576 | dirty.render_settings = false; | 582 | dirty[VideoCommon::Dirty::RenderTargets] = false; |
| 577 | 583 | ||
| 578 | texture_cache.GuardRenderTargets(true); | 584 | texture_cache.GuardRenderTargets(true); |
| 579 | 585 | ||
| @@ -723,13 +729,13 @@ void RasterizerVulkan::SetupImageTransitions( | |||
| 723 | } | 729 | } |
| 724 | 730 | ||
| 725 | void RasterizerVulkan::UpdateDynamicStates() { | 731 | void RasterizerVulkan::UpdateDynamicStates() { |
| 726 | auto& gpu = system.GPU().Maxwell3D(); | 732 | auto& regs = system.GPU().Maxwell3D().regs; |
| 727 | UpdateViewportsState(gpu); | 733 | UpdateViewportsState(regs); |
| 728 | UpdateScissorsState(gpu); | 734 | UpdateScissorsState(regs); |
| 729 | UpdateDepthBias(gpu); | 735 | UpdateDepthBias(regs); |
| 730 | UpdateBlendConstants(gpu); | 736 | UpdateBlendConstants(regs); |
| 731 | UpdateDepthBounds(gpu); | 737 | UpdateDepthBounds(regs); |
| 732 | UpdateStencilFaces(gpu); | 738 | UpdateStencilFaces(regs); |
| 733 | } | 739 | } |
| 734 | 740 | ||
| 735 | void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input, | 741 | void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input, |
| @@ -979,12 +985,10 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima | |||
| 979 | image_views.push_back(ImageView{std::move(view), image_layout}); | 985 | image_views.push_back(ImageView{std::move(view), image_layout}); |
| 980 | } | 986 | } |
| 981 | 987 | ||
| 982 | void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { | 988 | void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs) { |
| 983 | if (!gpu.dirty.viewport_transform && scheduler.TouchViewports()) { | 989 | if (!state_tracker.TouchViewports()) { |
| 984 | return; | 990 | return; |
| 985 | } | 991 | } |
| 986 | gpu.dirty.viewport_transform = false; | ||
| 987 | const auto& regs = gpu.regs; | ||
| 988 | const std::array viewports{ | 992 | const std::array viewports{ |
| 989 | GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), | 993 | GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), |
| 990 | GetViewportState(device, regs, 2), GetViewportState(device, regs, 3), | 994 | GetViewportState(device, regs, 2), GetViewportState(device, regs, 3), |
| @@ -999,12 +1003,10 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { | |||
| 999 | }); | 1003 | }); |
| 1000 | } | 1004 | } |
| 1001 | 1005 | ||
| 1002 | void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { | 1006 | void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs) { |
| 1003 | if (!gpu.dirty.scissor_test && scheduler.TouchScissors()) { | 1007 | if (!state_tracker.TouchScissors()) { |
| 1004 | return; | 1008 | return; |
| 1005 | } | 1009 | } |
| 1006 | gpu.dirty.scissor_test = false; | ||
| 1007 | const auto& regs = gpu.regs; | ||
| 1008 | const std::array scissors = { | 1010 | const std::array scissors = { |
| 1009 | GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), | 1011 | GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), |
| 1010 | GetScissorState(regs, 3), GetScissorState(regs, 4), GetScissorState(regs, 5), | 1012 | GetScissorState(regs, 3), GetScissorState(regs, 4), GetScissorState(regs, 5), |
| @@ -1017,46 +1019,39 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { | |||
| 1017 | }); | 1019 | }); |
| 1018 | } | 1020 | } |
| 1019 | 1021 | ||
| 1020 | void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { | 1022 | void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { |
| 1021 | if (!gpu.dirty.polygon_offset && scheduler.TouchDepthBias()) { | 1023 | if (!state_tracker.TouchDepthBias()) { |
| 1022 | return; | 1024 | return; |
| 1023 | } | 1025 | } |
| 1024 | gpu.dirty.polygon_offset = false; | ||
| 1025 | const auto& regs = gpu.regs; | ||
| 1026 | scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, | 1026 | scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, |
| 1027 | factor = regs.polygon_offset_factor](auto cmdbuf, auto& dld) { | 1027 | factor = regs.polygon_offset_factor](auto cmdbuf, auto& dld) { |
| 1028 | cmdbuf.setDepthBias(constant, clamp, factor / 2.0f, dld); | 1028 | cmdbuf.setDepthBias(constant, clamp, factor / 2.0f, dld); |
| 1029 | }); | 1029 | }); |
| 1030 | } | 1030 | } |
| 1031 | 1031 | ||
| 1032 | void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { | 1032 | void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& regs) { |
| 1033 | if (!gpu.dirty.blend_state && scheduler.TouchBlendConstants()) { | 1033 | if (!state_tracker.TouchBlendConstants()) { |
| 1034 | return; | 1034 | return; |
| 1035 | } | 1035 | } |
| 1036 | gpu.dirty.blend_state = false; | 1036 | const std::array blend_color = {regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, |
| 1037 | const std::array blend_color = {gpu.regs.blend_color.r, gpu.regs.blend_color.g, | 1037 | regs.blend_color.a}; |
| 1038 | gpu.regs.blend_color.b, gpu.regs.blend_color.a}; | ||
| 1039 | scheduler.Record([blend_color](auto cmdbuf, auto& dld) { | 1038 | scheduler.Record([blend_color](auto cmdbuf, auto& dld) { |
| 1040 | cmdbuf.setBlendConstants(blend_color.data(), dld); | 1039 | cmdbuf.setBlendConstants(blend_color.data(), dld); |
| 1041 | }); | 1040 | }); |
| 1042 | } | 1041 | } |
| 1043 | 1042 | ||
| 1044 | void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu) { | 1043 | void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D::Regs& regs) { |
| 1045 | if (!gpu.dirty.depth_bounds_values && scheduler.TouchDepthBounds()) { | 1044 | if (!state_tracker.TouchDepthBounds()) { |
| 1046 | return; | 1045 | return; |
| 1047 | } | 1046 | } |
| 1048 | gpu.dirty.depth_bounds_values = false; | ||
| 1049 | const auto& regs = gpu.regs; | ||
| 1050 | scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( | 1047 | scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( |
| 1051 | auto cmdbuf, auto& dld) { cmdbuf.setDepthBounds(min, max, dld); }); | 1048 | auto cmdbuf, auto& dld) { cmdbuf.setDepthBounds(min, max, dld); }); |
| 1052 | } | 1049 | } |
| 1053 | 1050 | ||
| 1054 | void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu) { | 1051 | void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) { |
| 1055 | if (!gpu.dirty.stencil_test && scheduler.TouchStencilValues()) { | 1052 | if (!state_tracker.TouchStencilProperties()) { |
| 1056 | return; | 1053 | return; |
| 1057 | } | 1054 | } |
| 1058 | gpu.dirty.stencil_test = false; | ||
| 1059 | const auto& regs = gpu.regs; | ||
| 1060 | if (regs.stencil_two_side_enable) { | 1055 | if (regs.stencil_two_side_enable) { |
| 1061 | // Separate values per face | 1056 | // Separate values per face |
| 1062 | scheduler.Record( | 1057 | scheduler.Record( |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 4dc8af6e8..96ea05f0a 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; |
| @@ -215,12 +217,12 @@ private: | |||
| 215 | 217 | ||
| 216 | void SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); | 218 | void SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); |
| 217 | 219 | ||
| 218 | void UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu); | 220 | void UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs); |
| 219 | void UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu); | 221 | void UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs); |
| 220 | void UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu); | 222 | void UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs); |
| 221 | void UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu); | 223 | void UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& regs); |
| 222 | void UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu); | 224 | void UpdateDepthBounds(Tegra::Engines::Maxwell3D::Regs& regs); |
| 223 | void UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu); | 225 | void UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs); |
| 224 | 226 | ||
| 225 | std::size_t CalculateGraphicsStreamBufferSize(bool is_indexed) const; | 227 | std::size_t CalculateGraphicsStreamBufferSize(bool is_indexed) const; |
| 226 | 228 | ||
| @@ -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..d74e68b63 --- /dev/null +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp | |||
| @@ -0,0 +1,101 @@ | |||
| 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 <algorithm> | ||
| 6 | #include <cstddef> | ||
| 7 | #include <iterator> | ||
| 8 | |||
| 9 | #include "common/common_types.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "video_core/dirty_flags.h" | ||
| 12 | #include "video_core/engines/maxwell_3d.h" | ||
| 13 | #include "video_core/gpu.h" | ||
| 14 | #include "video_core/renderer_vulkan/vk_state_tracker.h" | ||
| 15 | |||
| 16 | #define OFF(field_name) MAXWELL3D_REG_INDEX(field_name) | ||
| 17 | #define NUM(field_name) (sizeof(Maxwell3D::Regs::field_name) / sizeof(u32)) | ||
| 18 | |||
| 19 | namespace Vulkan { | ||
| 20 | |||
| 21 | namespace { | ||
| 22 | |||
| 23 | using namespace Dirty; | ||
| 24 | using namespace VideoCommon::Dirty; | ||
| 25 | using Tegra::Engines::Maxwell3D; | ||
| 26 | using Regs = Maxwell3D::Regs; | ||
| 27 | using Tables = Maxwell3D::DirtyState::Tables; | ||
| 28 | using Table = Maxwell3D::DirtyState::Table; | ||
| 29 | using Flags = Maxwell3D::DirtyState::Flags; | ||
| 30 | |||
| 31 | Flags MakeInvalidationFlags() { | ||
| 32 | Flags flags{}; | ||
| 33 | flags[Viewports] = true; | ||
| 34 | flags[Scissors] = true; | ||
| 35 | flags[DepthBias] = true; | ||
| 36 | flags[BlendConstants] = true; | ||
| 37 | flags[DepthBounds] = true; | ||
| 38 | flags[StencilProperties] = true; | ||
| 39 | return flags; | ||
| 40 | } | ||
| 41 | |||
| 42 | void SetupDirtyViewports(Tables& tables) { | ||
| 43 | FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); | ||
| 44 | FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); | ||
| 45 | tables[0][OFF(viewport_transform_enabled)] = Viewports; | ||
| 46 | } | ||
| 47 | |||
| 48 | void SetupDirtyScissors(Tables& tables) { | ||
| 49 | FillBlock(tables[0], OFF(scissor_test), NUM(scissor_test), Scissors); | ||
| 50 | } | ||
| 51 | |||
| 52 | void SetupDirtyDepthBias(Tables& tables) { | ||
| 53 | auto& table = tables[0]; | ||
| 54 | table[OFF(polygon_offset_units)] = DepthBias; | ||
| 55 | table[OFF(polygon_offset_clamp)] = DepthBias; | ||
| 56 | table[OFF(polygon_offset_factor)] = DepthBias; | ||
| 57 | } | ||
| 58 | |||
| 59 | void SetupDirtyBlendConstants(Tables& tables) { | ||
| 60 | FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendConstants); | ||
| 61 | } | ||
| 62 | |||
| 63 | void SetupDirtyDepthBounds(Tables& tables) { | ||
| 64 | FillBlock(tables[0], OFF(depth_bounds), NUM(depth_bounds), DepthBounds); | ||
| 65 | } | ||
| 66 | |||
| 67 | void SetupDirtyStencilProperties(Tables& tables) { | ||
| 68 | auto& table = tables[0]; | ||
| 69 | table[OFF(stencil_two_side_enable)] = StencilProperties; | ||
| 70 | table[OFF(stencil_front_func_ref)] = StencilProperties; | ||
| 71 | table[OFF(stencil_front_mask)] = StencilProperties; | ||
| 72 | table[OFF(stencil_front_func_mask)] = StencilProperties; | ||
| 73 | table[OFF(stencil_back_func_ref)] = StencilProperties; | ||
| 74 | table[OFF(stencil_back_mask)] = StencilProperties; | ||
| 75 | table[OFF(stencil_back_func_mask)] = StencilProperties; | ||
| 76 | } | ||
| 77 | |||
| 78 | } // Anonymous namespace | ||
| 79 | |||
| 80 | StateTracker::StateTracker(Core::System& system) | ||
| 81 | : system{system}, invalidation_flags{MakeInvalidationFlags()} {} | ||
| 82 | |||
| 83 | void StateTracker::Initialize() { | ||
| 84 | auto& dirty = system.GPU().Maxwell3D().dirty; | ||
| 85 | auto& tables = dirty.tables; | ||
| 86 | SetupDirtyRenderTargets(tables); | ||
| 87 | SetupDirtyViewports(tables); | ||
| 88 | SetupDirtyScissors(tables); | ||
| 89 | SetupDirtyDepthBias(tables); | ||
| 90 | SetupDirtyBlendConstants(tables); | ||
| 91 | SetupDirtyDepthBounds(tables); | ||
| 92 | SetupDirtyStencilProperties(tables); | ||
| 93 | |||
| 94 | SetupCommonOnWriteStores(dirty.on_write_stores); | ||
| 95 | } | ||
| 96 | |||
| 97 | void StateTracker::InvalidateCommandBufferState() { | ||
| 98 | system.GPU().Maxwell3D().dirty.flags |= invalidation_flags; | ||
| 99 | } | ||
| 100 | |||
| 101 | } // 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..03bc415b2 --- /dev/null +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h | |||
| @@ -0,0 +1,79 @@ | |||
| 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 <cstddef> | ||
| 8 | #include <limits> | ||
| 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 | Scissors, | ||
| 24 | DepthBias, | ||
| 25 | BlendConstants, | ||
| 26 | DepthBounds, | ||
| 27 | StencilProperties, | ||
| 28 | |||
| 29 | Last | ||
| 30 | }; | ||
| 31 | static_assert(Last <= std::numeric_limits<u8>::max()); | ||
| 32 | |||
| 33 | } // namespace Dirty | ||
| 34 | |||
| 35 | class StateTracker { | ||
| 36 | public: | ||
| 37 | explicit StateTracker(Core::System& system); | ||
| 38 | |||
| 39 | void Initialize(); | ||
| 40 | |||
| 41 | void InvalidateCommandBufferState(); | ||
| 42 | |||
| 43 | bool TouchViewports() { | ||
| 44 | return Exchange(Dirty::Viewports, false); | ||
| 45 | } | ||
| 46 | |||
| 47 | bool TouchScissors() { | ||
| 48 | return Exchange(Dirty::Scissors, false); | ||
| 49 | } | ||
| 50 | |||
| 51 | bool TouchDepthBias() { | ||
| 52 | return Exchange(Dirty::DepthBias, false); | ||
| 53 | } | ||
| 54 | |||
| 55 | bool TouchBlendConstants() { | ||
| 56 | return Exchange(Dirty::BlendConstants, false); | ||
| 57 | } | ||
| 58 | |||
| 59 | bool TouchDepthBounds() { | ||
| 60 | return Exchange(Dirty::DepthBounds, false); | ||
| 61 | } | ||
| 62 | |||
| 63 | bool TouchStencilProperties() { | ||
| 64 | return Exchange(Dirty::StencilProperties, false); | ||
| 65 | } | ||
| 66 | |||
| 67 | private: | ||
| 68 | bool Exchange(std::size_t id, bool new_value) const noexcept { | ||
| 69 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 70 | const bool is_dirty = flags[id]; | ||
| 71 | flags[id] = new_value; | ||
| 72 | return is_dirty; | ||
| 73 | } | ||
| 74 | |||
| 75 | Core::System& system; | ||
| 76 | Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags; | ||
| 77 | }; | ||
| 78 | |||
| 79 | } // 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" |