From 96ac3d518a9882a2a040f319c47a567467c9266d Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 17:02:17 -0300 Subject: gl_rasterizer: Remove dirty flags --- .../renderer_vulkan/vk_pipeline_cache.cpp | 5 ---- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 28 +--------------------- 2 files changed, 1 insertion(+), 32 deletions(-) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 7ddf7d3ee..8186942da 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -172,11 +172,6 @@ VKPipelineCache::~VKPipelineCache() = default; std::array VKPipelineCache::GetShaders() { const auto& gpu = system.GPU().Maxwell3D(); - auto& dirty = system.GPU().Maxwell3D().dirty.shaders; - if (!dirty) { - return last_shaders; - } - dirty = false; std::array shaders; 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 3bf86da87..b1be41a21 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -568,9 +568,7 @@ void RasterizerVulkan::FlushWork() { RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { MICROPROFILE_SCOPE(Vulkan_RenderTargets); - auto& dirty = system.GPU().Maxwell3D().dirty; - const bool update_rendertargets = dirty.render_settings; - dirty.render_settings = false; + constexpr bool update_rendertargets = true; texture_cache.GuardRenderTargets(true); @@ -973,10 +971,6 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima } void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { - if (!gpu.dirty.viewport_transform && scheduler.TouchViewports()) { - return; - } - gpu.dirty.viewport_transform = false; const auto& regs = gpu.regs; const std::array viewports{ GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), @@ -993,10 +987,6 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { - if (!gpu.dirty.scissor_test && scheduler.TouchScissors()) { - return; - } - gpu.dirty.scissor_test = false; const auto& regs = gpu.regs; const std::array scissors = { GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), @@ -1011,10 +1001,6 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { - if (!gpu.dirty.polygon_offset && scheduler.TouchDepthBias()) { - return; - } - gpu.dirty.polygon_offset = false; const auto& regs = gpu.regs; scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, factor = regs.polygon_offset_factor](auto cmdbuf, auto& dld) { @@ -1023,10 +1009,6 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { - if (!gpu.dirty.blend_state && scheduler.TouchBlendConstants()) { - return; - } - gpu.dirty.blend_state = false; const std::array blend_color = {gpu.regs.blend_color.r, gpu.regs.blend_color.g, gpu.regs.blend_color.b, gpu.regs.blend_color.a}; scheduler.Record([blend_color](auto cmdbuf, auto& dld) { @@ -1035,20 +1017,12 @@ void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu) { - if (!gpu.dirty.depth_bounds_values && scheduler.TouchDepthBounds()) { - return; - } - gpu.dirty.depth_bounds_values = false; const auto& regs = gpu.regs; scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( auto cmdbuf, auto& dld) { cmdbuf.setDepthBounds(min, max, dld); }); } void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu) { - if (!gpu.dirty.stencil_test && scheduler.TouchStencilValues()) { - return; - } - gpu.dirty.stencil_test = false; const auto& regs = gpu.regs; if (regs.stencil_two_side_enable) { // Separate values per face -- cgit v1.2.3 From 9e74e6988b881c6889074bd2335239eb2e491e91 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 21:41:41 -0300 Subject: maxwell_3d: Flatten cull and front face registers --- src/video_core/renderer_vulkan/fixed_pipeline_state.cpp | 15 +++++++-------- src/video_core/renderer_vulkan/fixed_pipeline_state.h | 8 ++++---- src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 14 +++++++------- src/video_core/renderer_vulkan/maxwell_to_vk.h | 4 ++-- 4 files changed, 20 insertions(+), 21 deletions(-) (limited to 'src/video_core/renderer_vulkan') 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) const auto& clip = regs.view_volume_clip_control; const bool depth_clamp_enabled = clip.depth_clamp_near == 1 || clip.depth_clamp_far == 1; - Maxwell::Cull::FrontFace front_face = regs.cull.front_face; + Maxwell::FrontFace front_face = regs.front_face; if (regs.screen_y_control.triangle_rast_flip != 0 && regs.viewport_transform[0].scale_y > 0.0f) { - if (front_face == Maxwell::Cull::FrontFace::CounterClockWise) - front_face = Maxwell::Cull::FrontFace::ClockWise; - else if (front_face == Maxwell::Cull::FrontFace::ClockWise) - front_face = Maxwell::Cull::FrontFace::CounterClockWise; + if (front_face == Maxwell::FrontFace::CounterClockWise) + front_face = Maxwell::FrontFace::ClockWise; + else if (front_face == Maxwell::FrontFace::ClockWise) + front_face = Maxwell::FrontFace::CounterClockWise; } const bool gl_ndc = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; - return FixedPipelineState::Rasterizer(regs.cull.enabled, depth_bias_enabled, - depth_clamp_enabled, gl_ndc, regs.cull.cull_face, - front_face); + return FixedPipelineState::Rasterizer(regs.cull_test_enabled, depth_bias_enabled, + depth_clamp_enabled, gl_ndc, regs.cull_face, front_face); } } // 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 { struct Rasterizer { constexpr Rasterizer(bool cull_enable, bool depth_bias_enable, bool depth_clamp_enable, - bool ndc_minus_one_to_one, Maxwell::Cull::CullFace cull_face, - Maxwell::Cull::FrontFace front_face) + bool ndc_minus_one_to_one, Maxwell::CullFace cull_face, + Maxwell::FrontFace front_face) : cull_enable{cull_enable}, depth_bias_enable{depth_bias_enable}, depth_clamp_enable{depth_clamp_enable}, ndc_minus_one_to_one{ndc_minus_one_to_one}, cull_face{cull_face}, front_face{front_face} {} @@ -182,8 +182,8 @@ struct FixedPipelineState { bool depth_bias_enable; bool depth_clamp_enable; bool ndc_minus_one_to_one; - Maxwell::Cull::CullFace cull_face; - Maxwell::Cull::FrontFace front_face; + Maxwell::CullFace cull_face; + Maxwell::FrontFace front_face; std::size_t Hash() const noexcept; diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index ef66dd141..088b072ef 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -572,24 +572,24 @@ vk::BlendFactor BlendFactor(Maxwell::Blend::Factor factor) { return {}; } -vk::FrontFace FrontFace(Maxwell::Cull::FrontFace front_face) { +vk::FrontFace FrontFace(Maxwell::FrontFace front_face) { switch (front_face) { - case Maxwell::Cull::FrontFace::ClockWise: + case Maxwell::FrontFace::ClockWise: return vk::FrontFace::eClockwise; - case Maxwell::Cull::FrontFace::CounterClockWise: + case Maxwell::FrontFace::CounterClockWise: return vk::FrontFace::eCounterClockwise; } UNIMPLEMENTED_MSG("Unimplemented front face={}", static_cast(front_face)); return {}; } -vk::CullModeFlags CullFace(Maxwell::Cull::CullFace cull_face) { +vk::CullModeFlags CullFace(Maxwell::CullFace cull_face) { switch (cull_face) { - case Maxwell::Cull::CullFace::Front: + case Maxwell::CullFace::Front: return vk::CullModeFlagBits::eFront; - case Maxwell::Cull::CullFace::Back: + case Maxwell::CullFace::Back: return vk::CullModeFlagBits::eBack; - case Maxwell::Cull::CullFace::FrontAndBack: + case Maxwell::CullFace::FrontAndBack: return vk::CullModeFlagBits::eFrontAndBack; } UNIMPLEMENTED_MSG("Unimplemented cull face={}", static_cast(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); vk::BlendFactor BlendFactor(Maxwell::Blend::Factor factor); -vk::FrontFace FrontFace(Maxwell::Cull::FrontFace front_face); +vk::FrontFace FrontFace(Maxwell::FrontFace front_face); -vk::CullModeFlags CullFace(Maxwell::Cull::CullFace cull_face); +vk::CullModeFlags CullFace(Maxwell::CullFace cull_face); vk::ComponentSwizzle SwizzleSource(Tegra::Texture::SwizzleSource swizzle); -- cgit v1.2.3 From 1bd95a314f07732319a71fca2aba81d400ca4c83 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 20 Feb 2020 20:35:53 -0300 Subject: vk_state_tracker: Initial implementation Add support for render targets and viewports. --- src/video_core/renderer_vulkan/renderer_vulkan.cpp | 8 +- src/video_core/renderer_vulkan/renderer_vulkan.h | 4 + src/video_core/renderer_vulkan/vk_rasterizer.cpp | 17 +++- src/video_core/renderer_vulkan/vk_rasterizer.h | 5 +- src/video_core/renderer_vulkan/vk_scheduler.cpp | 21 +++-- src/video_core/renderer_vulkan/vk_scheduler.h | 42 ++-------- .../renderer_vulkan/vk_state_tracker.cpp | 97 ++++++++++++++++++++++ src/video_core/renderer_vulkan/vk_state_tracker.h | 53 ++++++++++++ .../renderer_vulkan/vk_texture_cache.cpp | 1 + 9 files changed, 196 insertions(+), 52 deletions(-) create mode 100644 src/video_core/renderer_vulkan/vk_state_tracker.cpp create mode 100644 src/video_core/renderer_vulkan/vk_state_tracker.h (limited to 'src/video_core/renderer_vulkan') 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 @@ #include "video_core/renderer_vulkan/vk_rasterizer.h" #include "video_core/renderer_vulkan/vk_resource_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_state_tracker.h" #include "video_core/renderer_vulkan/vk_swapchain.h" namespace Vulkan { @@ -177,10 +178,13 @@ bool RendererVulkan::Init() { swapchain = std::make_unique(surface, *device); swapchain->Create(framebuffer.width, framebuffer.height, false); - scheduler = std::make_unique(*device, *resource_manager); + state_tracker = std::make_unique(system); + + scheduler = std::make_unique(*device, *resource_manager, *state_tracker); rasterizer = std::make_unique(system, render_window, screen_info, *device, - *resource_manager, *memory_manager, *scheduler); + *resource_manager, *memory_manager, + *state_tracker, *scheduler); blit_screen = std::make_unique(system, render_window, *rasterizer, *device, *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 @@ #pragma once +#include #include #include + #include "video_core/renderer_base.h" #include "video_core/renderer_vulkan/declarations.h" @@ -15,6 +17,7 @@ class System; namespace Vulkan { +class StateTracker; class VKBlitScreen; class VKDevice; class VKFence; @@ -61,6 +64,7 @@ private: std::unique_ptr swapchain; std::unique_ptr memory_manager; std::unique_ptr resource_manager; + std::unique_ptr state_tracker; std::unique_ptr scheduler; std::unique_ptr blit_screen; }; 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 @@ #include "video_core/renderer_vulkan/vk_sampler_cache.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" +#include "video_core/renderer_vulkan/vk_state_tracker.h" #include "video_core/renderer_vulkan/vk_texture_cache.h" #include "video_core/renderer_vulkan/vk_update_descriptor.h" @@ -277,10 +278,11 @@ void RasterizerVulkan::DrawParameters::Draw(vk::CommandBuffer cmdbuf, RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer, VKScreenInfo& screen_info, const VKDevice& device, VKResourceManager& resource_manager, - VKMemoryManager& memory_manager, VKScheduler& scheduler) + VKMemoryManager& memory_manager, StateTracker& state_tracker, + VKScheduler& scheduler) : RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer}, screen_info{screen_info}, device{device}, resource_manager{resource_manager}, - memory_manager{memory_manager}, scheduler{scheduler}, + memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler}, staging_pool(device, memory_manager, scheduler), descriptor_pool(device), update_descriptor_queue(device, scheduler), quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), @@ -545,6 +547,10 @@ bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, return true; } +void RasterizerVulkan::SetupDirtyFlags() { + state_tracker.Initialize(); +} + void RasterizerVulkan::FlushWork() { static constexpr u32 DRAWS_TO_DISPATCH = 4096; @@ -568,7 +574,9 @@ void RasterizerVulkan::FlushWork() { RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { MICROPROFILE_SCOPE(Vulkan_RenderTargets); - constexpr bool update_rendertargets = true; + auto& dirty = system.GPU().Maxwell3D().dirty.flags; + const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets]; + dirty[VideoCommon::Dirty::RenderTargets] = false; texture_cache.GuardRenderTargets(true); @@ -971,6 +979,9 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima } void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { + if (!state_tracker.TouchViewports()) { + return; + } const auto& regs = gpu.regs; const std::array viewports{ 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 { namespace Vulkan { +class StateTracker; class BufferBindings; struct ImageView { @@ -108,7 +109,7 @@ public: explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window, VKScreenInfo& screen_info, const VKDevice& device, VKResourceManager& resource_manager, VKMemoryManager& memory_manager, - VKScheduler& scheduler); + StateTracker& state_tracker, VKScheduler& scheduler); ~RasterizerVulkan() override; void Draw(bool is_indexed, bool is_instanced) override; @@ -127,6 +128,7 @@ public: const Tegra::Engines::Fermi2D::Config& copy_config) override; bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, u32 pixel_stride) override; + void SetupDirtyFlags() override; /// Maximum supported size that a constbuffer can have in bytes. static constexpr std::size_t MaxConstbufferSize = 0x10000; @@ -241,6 +243,7 @@ private: const VKDevice& device; VKResourceManager& resource_manager; VKMemoryManager& memory_manager; + StateTracker& state_tracker; VKScheduler& scheduler; 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 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include +#include +#include +#include + #include "common/assert.h" #include "common/microprofile.h" #include "video_core/renderer_vulkan/declarations.h" @@ -9,6 +15,7 @@ #include "video_core/renderer_vulkan/vk_query_cache.h" #include "video_core/renderer_vulkan/vk_resource_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" +#include "video_core/renderer_vulkan/vk_state_tracker.h" namespace Vulkan { @@ -29,9 +36,10 @@ void VKScheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf, last = nullptr; } -VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager) - : device{device}, resource_manager{resource_manager}, next_fence{ - &resource_manager.CommitFence()} { +VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager, + StateTracker& state_tracker) + : device{device}, resource_manager{resource_manager}, state_tracker{state_tracker}, + next_fence{&resource_manager.CommitFence()} { AcquireNewChunk(); AllocateNewContext(); worker_thread = std::thread(&VKScheduler::WorkerThread, this); @@ -157,12 +165,7 @@ void VKScheduler::AllocateNewContext() { void VKScheduler::InvalidateState() { state.graphics_pipeline = nullptr; - state.viewports = false; - state.scissors = false; - state.depth_bias = false; - state.blend_constants = false; - state.depth_bounds = false; - state.stencil_values = false; + state_tracker.InvalidateCommandBufferState(); } 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 @@ namespace Vulkan { +class StateTracker; class VKDevice; class VKFence; class VKQueryCache; @@ -43,7 +44,8 @@ private: /// OpenGL-like operations on Vulkan command buffers. class VKScheduler { public: - explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager); + explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager, + StateTracker& state_tracker); ~VKScheduler(); /// Sends the current execution context to the GPU. @@ -74,36 +76,6 @@ public: query_cache = &query_cache_; } - /// Returns true when viewports have been set in the current command buffer. - bool TouchViewports() { - return std::exchange(state.viewports, true); - } - - /// Returns true when scissors have been set in the current command buffer. - bool TouchScissors() { - return std::exchange(state.scissors, true); - } - - /// Returns true when depth bias have been set in the current command buffer. - bool TouchDepthBias() { - return std::exchange(state.depth_bias, true); - } - - /// Returns true when blend constants have been set in the current command buffer. - bool TouchBlendConstants() { - return std::exchange(state.blend_constants, true); - } - - /// Returns true when depth bounds have been set in the current command buffer. - bool TouchDepthBounds() { - return std::exchange(state.depth_bounds, true); - } - - /// Returns true when stencil values have been set in the current command buffer. - bool TouchStencilValues() { - return std::exchange(state.stencil_values, true); - } - /// Send work to a separate thread. template void Record(T&& command) { @@ -217,6 +189,8 @@ private: const VKDevice& device; VKResourceManager& resource_manager; + StateTracker& state_tracker; + VKQueryCache* query_cache = nullptr; vk::CommandBuffer current_cmdbuf; @@ -226,12 +200,6 @@ private: struct State { std::optional renderpass; vk::Pipeline graphics_pipeline; - bool viewports = false; - bool scissors = false; - bool depth_bias = false; - bool blend_constants = false; - bool depth_bounds = false; - bool stencil_values = false; } state; std::unique_ptr 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 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include + +#include "common/common_types.h" +#include "core/core.h" +#include "video_core/engines/maxwell_3d.h" +#include "video_core/gpu.h" +#include "video_core/renderer_vulkan/vk_state_tracker.h" + +#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name) +#define NUM(field_name) (sizeof(Maxwell3D::Regs::field_name) / sizeof(u32)) + +namespace Vulkan { + +namespace { + +using namespace Dirty; +using namespace VideoCommon::Dirty; +using Tegra::Engines::Maxwell3D; +using Regs = Maxwell3D::Regs; +using Dirty = std::remove_reference_t; +using Tables = std::remove_reference_t; +using Table = std::remove_reference_t; +using Flags = std::remove_reference_t; + +Flags MakeInvalidationFlags() { + Flags flags{}; + flags[Viewports] = true; + return flags; +} + +template +void FillBlock(Table& table, std::size_t begin, std::size_t num, Integer dirty_index) { + const auto it = std::begin(table) + begin; + std::fill(it, it + num, static_cast(dirty_index)); +} + +template +void FillBlock(Tables& tables, std::size_t begin, std::size_t num, Integer1 index_a, + Integer2 index_b) { + FillBlock(tables[0], begin, num, index_a); + FillBlock(tables[1], begin, num, index_b); +} + +void SetupDirtyRenderTargets(Tables& tables) { + static constexpr std::size_t num_per_rt = NUM(rt[0]); + static constexpr std::size_t begin = OFF(rt); + static constexpr std::size_t num = num_per_rt * Regs::NumRenderTargets; + for (std::size_t rt = 0; rt < Regs::NumRenderTargets; ++rt) { + FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt); + } + FillBlock(tables[1], begin, num, RenderTargets); + + static constexpr std::array zeta_flags{ZetaBuffer, RenderTargets}; + for (std::size_t i = 0; i < std::size(zeta_flags); ++i) { + const u8 flag = zeta_flags[i]; + auto& table = tables[i]; + table[OFF(zeta_enable)] = flag; + table[OFF(zeta_width)] = flag; + table[OFF(zeta_height)] = flag; + FillBlock(table, OFF(zeta), NUM(zeta), flag); + } +} + +void SetupDirtyViewports(Tables& tables) { + FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); + FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); + tables[0][OFF(viewport_transform_enabled)] = Viewports; +} + +} // Anonymous namespace + +StateTracker::StateTracker(Core::System& system) + : system{system}, invalidation_flags{MakeInvalidationFlags()} {} + +void StateTracker::Initialize() { + auto& dirty = system.GPU().Maxwell3D().dirty; + auto& tables = dirty.tables; + SetupDirtyRenderTargets(tables); + SetupDirtyViewports(tables); + + auto& store = dirty.on_write_stores; + store[RenderTargets] = true; + store[ZetaBuffer] = true; + for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) { + store[ColorBuffer0 + i] = true; + } +} + +void StateTracker::InvalidateCommandBufferState() { + system.GPU().Maxwell3D().dirty.flags |= invalidation_flags; +} + +} // 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 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include // REMOVE ME +#include + +#include "common/common_types.h" +#include "core/core.h" +#include "video_core/dirty_flags.h" +#include "video_core/engines/maxwell_3d.h" + +namespace Vulkan { + +namespace Dirty { + +enum : u8 { + First = VideoCommon::Dirty::LastCommonEntry, + + Viewports, +}; + +} // namespace Dirty + +class StateTracker { +public: + explicit StateTracker(Core::System& system); + + void Initialize(); + + void InvalidateCommandBufferState(); + + bool TouchViewports() { + return Exchange(Dirty::Viewports, false); + } + +private: + using Flags = std::remove_reference_t; + + bool Exchange(std::size_t id, bool new_value) const noexcept { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + const bool is_dirty = flags[id]; + flags[id] = new_value; + return is_dirty; + } + + Core::System& system; + Flags invalidation_flags; +}; + +} // 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 @@ #include "video_core/renderer_vulkan/vk_device.h" #include "video_core/renderer_vulkan/vk_memory_manager.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" +#include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" #include "video_core/renderer_vulkan/vk_texture_cache.h" #include "video_core/surface.h" -- cgit v1.2.3 From 42f18749658bb4f3ce2e6be7677596d41ac8cd6c Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 20 Feb 2020 22:19:57 -0300 Subject: vk_state_tracker: Implement dirty flags for scissors --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 3 +++ src/video_core/renderer_vulkan/vk_state_tracker.cpp | 6 ++++++ src/video_core/renderer_vulkan/vk_state_tracker.h | 5 +++++ 3 files changed, 14 insertions(+) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 41cbf4134..207ef0f0d 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -998,6 +998,9 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { + if (!state_tracker.TouchScissors()) { + return; + } const auto& regs = gpu.regs; const std::array scissors = { GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index d44992dc9..0e00a9079 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -29,6 +29,7 @@ using Flags = std::remove_reference_t; Flags MakeInvalidationFlags() { Flags flags{}; flags[Viewports] = true; + flags[Scissors] = true; return flags; } @@ -71,6 +72,10 @@ void SetupDirtyViewports(Tables& tables) { tables[0][OFF(viewport_transform_enabled)] = Viewports; } +void SetupDirtyScissors(Tables& tables) { + FillBlock(tables[0], OFF(scissor_test), NUM(scissor_test), Scissors); +} + } // Anonymous namespace StateTracker::StateTracker(Core::System& system) @@ -81,6 +86,7 @@ void StateTracker::Initialize() { auto& tables = dirty.tables; SetupDirtyRenderTargets(tables); SetupDirtyViewports(tables); + SetupDirtyScissors(tables); auto& store = dirty.on_write_stores; store[RenderTargets] = true; diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 9ec7b5136..ba8f3a854 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -20,6 +20,7 @@ enum : u8 { First = VideoCommon::Dirty::LastCommonEntry, Viewports, + Scissors, }; } // namespace Dirty @@ -36,6 +37,10 @@ public: return Exchange(Dirty::Viewports, false); } + bool TouchScissors() { + return Exchange(Dirty::Scissors, false); + } + private: using Flags = std::remove_reference_t; -- cgit v1.2.3 From a33870996b00f18179048debf183f1cb5c499593 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 00:28:45 -0300 Subject: vk_state_tracker: Implement dirty flags for depth bias --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 3 +++ src/video_core/renderer_vulkan/vk_state_tracker.cpp | 9 +++++++++ src/video_core/renderer_vulkan/vk_state_tracker.h | 5 +++++ 3 files changed, 17 insertions(+) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 207ef0f0d..be2c4d149 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1015,6 +1015,9 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { + if (!state_tracker.TouchDepthBias()) { + return; + } const auto& regs = gpu.regs; scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, factor = regs.polygon_offset_factor](auto cmdbuf, auto& dld) { diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index 0e00a9079..c75caaa56 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -30,6 +30,7 @@ Flags MakeInvalidationFlags() { Flags flags{}; flags[Viewports] = true; flags[Scissors] = true; + flags[DepthBias] = true; return flags; } @@ -76,6 +77,13 @@ void SetupDirtyScissors(Tables& tables) { FillBlock(tables[0], OFF(scissor_test), NUM(scissor_test), Scissors); } +void SetupDirtyDepthBias(Tables& tables) { + auto& table = tables[0]; + table[OFF(polygon_offset_units)] = DepthBias; + table[OFF(polygon_offset_clamp)] = DepthBias; + table[OFF(polygon_offset_factor)] = DepthBias; +} + } // Anonymous namespace StateTracker::StateTracker(Core::System& system) @@ -87,6 +95,7 @@ void StateTracker::Initialize() { SetupDirtyRenderTargets(tables); SetupDirtyViewports(tables); SetupDirtyScissors(tables); + SetupDirtyDepthBias(tables); auto& store = dirty.on_write_stores; store[RenderTargets] = true; diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index ba8f3a854..088b47145 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -21,6 +21,7 @@ enum : u8 { Viewports, Scissors, + DepthBias, }; } // namespace Dirty @@ -41,6 +42,10 @@ public: return Exchange(Dirty::Scissors, false); } + bool TouchDepthBias() { + return Exchange(Dirty::DepthBias, false); + } + private: using Flags = std::remove_reference_t; -- cgit v1.2.3 From cd0e28c9ecb2ecd4579ad9abb8899255f60334da Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 00:37:29 -0300 Subject: vk_state_tracker: Implement dirty flags for blend constants --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 3 +++ src/video_core/renderer_vulkan/vk_state_tracker.cpp | 6 ++++++ src/video_core/renderer_vulkan/vk_state_tracker.h | 5 +++++ 3 files changed, 14 insertions(+) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index be2c4d149..958f90f99 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1026,6 +1026,9 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { + if (!state_tracker.TouchBlendConstants()) { + return; + } const std::array blend_color = {gpu.regs.blend_color.r, gpu.regs.blend_color.g, gpu.regs.blend_color.b, gpu.regs.blend_color.a}; scheduler.Record([blend_color](auto cmdbuf, auto& dld) { diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index c75caaa56..c7e54c68b 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -31,6 +31,7 @@ Flags MakeInvalidationFlags() { flags[Viewports] = true; flags[Scissors] = true; flags[DepthBias] = true; + flags[BlendConstants] = true; return flags; } @@ -84,6 +85,10 @@ void SetupDirtyDepthBias(Tables& tables) { table[OFF(polygon_offset_factor)] = DepthBias; } +void SetupDirtyBlendConstants(Tables& tables) { + FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendConstants); +} + } // Anonymous namespace StateTracker::StateTracker(Core::System& system) @@ -96,6 +101,7 @@ void StateTracker::Initialize() { SetupDirtyViewports(tables); SetupDirtyScissors(tables); SetupDirtyDepthBias(tables); + SetupDirtyBlendConstants(tables); auto& store = dirty.on_write_stores; store[RenderTargets] = true; diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 088b47145..a0493813a 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -22,6 +22,7 @@ enum : u8 { Viewports, Scissors, DepthBias, + BlendConstants, }; } // namespace Dirty @@ -46,6 +47,10 @@ public: return Exchange(Dirty::DepthBias, false); } + bool TouchBlendConstants() { + return Exchange(Dirty::BlendConstants, false); + } + private: using Flags = std::remove_reference_t; -- cgit v1.2.3 From f9df2c6bcdc1a6129289fb2878d4471c04e55fc7 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 00:54:39 -0300 Subject: vk_state_tracker: Implement dirty flags for depth bounds --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 3 +++ src/video_core/renderer_vulkan/vk_state_tracker.cpp | 6 ++++++ src/video_core/renderer_vulkan/vk_state_tracker.h | 5 +++++ 3 files changed, 14 insertions(+) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 958f90f99..7029b3d5e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1037,6 +1037,9 @@ void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu) { + if (!state_tracker.TouchDepthBounds()) { + return; + } const auto& regs = gpu.regs; scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( auto cmdbuf, auto& dld) { cmdbuf.setDepthBounds(min, max, dld); }); diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index c7e54c68b..b55180dd8 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -32,6 +32,7 @@ Flags MakeInvalidationFlags() { flags[Scissors] = true; flags[DepthBias] = true; flags[BlendConstants] = true; + flags[DepthBounds] = true; return flags; } @@ -89,6 +90,10 @@ void SetupDirtyBlendConstants(Tables& tables) { FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendConstants); } +void SetupDirtyDepthBounds(Tables& tables) { + FillBlock(tables[0], OFF(depth_bounds), NUM(depth_bounds), DepthBounds); +} + } // Anonymous namespace StateTracker::StateTracker(Core::System& system) @@ -102,6 +107,7 @@ void StateTracker::Initialize() { SetupDirtyScissors(tables); SetupDirtyDepthBias(tables); SetupDirtyBlendConstants(tables); + SetupDirtyDepthBounds(tables); auto& store = dirty.on_write_stores; store[RenderTargets] = true; diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index a0493813a..25b5c647b 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -23,6 +23,7 @@ enum : u8 { Scissors, DepthBias, BlendConstants, + DepthBounds, }; } // namespace Dirty @@ -51,6 +52,10 @@ public: return Exchange(Dirty::BlendConstants, false); } + bool TouchDepthBounds() { + return Exchange(Dirty::DepthBounds, false); + } + private: using Flags = std::remove_reference_t; -- cgit v1.2.3 From 6ac3eb4d87af7793d805dc9f7fc43f45e59e212e Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 01:09:02 -0300 Subject: vk_state_tracker: Implement dirty flags for stencil properties --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 3 +++ src/video_core/renderer_vulkan/vk_state_tracker.cpp | 13 +++++++++++++ src/video_core/renderer_vulkan/vk_state_tracker.h | 5 +++++ 3 files changed, 21 insertions(+) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 7029b3d5e..eb9c49d5e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1046,6 +1046,9 @@ void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu) { } void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu) { + if (!state_tracker.TouchStencilProperties()) { + return; + } const auto& regs = gpu.regs; if (regs.stencil_two_side_enable) { // Separate values per face diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index b55180dd8..3fd0476b6 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -33,6 +33,7 @@ Flags MakeInvalidationFlags() { flags[DepthBias] = true; flags[BlendConstants] = true; flags[DepthBounds] = true; + flags[StencilProperties] = true; return flags; } @@ -94,6 +95,17 @@ void SetupDirtyDepthBounds(Tables& tables) { FillBlock(tables[0], OFF(depth_bounds), NUM(depth_bounds), DepthBounds); } +void SetupDirtyStencilProperties(Tables& tables) { + auto& table = tables[0]; + table[OFF(stencil_two_side_enable)] = StencilProperties; + table[OFF(stencil_front_func_ref)] = StencilProperties; + table[OFF(stencil_front_mask)] = StencilProperties; + table[OFF(stencil_front_func_mask)] = StencilProperties; + table[OFF(stencil_back_func_ref)] = StencilProperties; + table[OFF(stencil_back_mask)] = StencilProperties; + table[OFF(stencil_back_func_mask)] = StencilProperties; +} + } // Anonymous namespace StateTracker::StateTracker(Core::System& system) @@ -108,6 +120,7 @@ void StateTracker::Initialize() { SetupDirtyDepthBias(tables); SetupDirtyBlendConstants(tables); SetupDirtyDepthBounds(tables); + SetupDirtyStencilProperties(tables); auto& store = dirty.on_write_stores; store[RenderTargets] = true; diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 25b5c647b..1d8434dd0 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -24,6 +24,7 @@ enum : u8 { DepthBias, BlendConstants, DepthBounds, + StencilProperties, }; } // namespace Dirty @@ -56,6 +57,10 @@ public: return Exchange(Dirty::DepthBounds, false); } + bool TouchStencilProperties() { + return Exchange(Dirty::StencilProperties, false); + } + private: using Flags = std::remove_reference_t; -- cgit v1.2.3 From 042256c6bbbe27a71805aa2dabe2cac436134b3d Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 01:19:07 -0300 Subject: state_tracker: Remove type traits with named structures --- src/video_core/renderer_vulkan/vk_state_tracker.cpp | 11 ++++++----- src/video_core/renderer_vulkan/vk_state_tracker.h | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index 3fd0476b6..67229ffcc 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -2,7 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include +#include +#include +#include #include "common/common_types.h" #include "core/core.h" @@ -21,10 +23,9 @@ using namespace Dirty; using namespace VideoCommon::Dirty; using Tegra::Engines::Maxwell3D; using Regs = Maxwell3D::Regs; -using Dirty = std::remove_reference_t; -using Tables = std::remove_reference_t; -using Table = std::remove_reference_t; -using Flags = std::remove_reference_t; +using Tables = Maxwell3D::DirtyState::Tables; +using Table = Maxwell3D::DirtyState::Table; +using Flags = Maxwell3D::DirtyState::Flags; Flags MakeInvalidationFlags() { Flags flags{}; diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 1d8434dd0..03bc415b2 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h @@ -4,8 +4,8 @@ #pragma once -#include // REMOVE ME -#include +#include +#include #include "common/common_types.h" #include "core/core.h" @@ -25,7 +25,10 @@ enum : u8 { BlendConstants, DepthBounds, StencilProperties, + + Last }; +static_assert(Last <= std::numeric_limits::max()); } // namespace Dirty @@ -62,8 +65,6 @@ public: } private: - using Flags = std::remove_reference_t; - bool Exchange(std::size_t id, bool new_value) const noexcept { auto& flags = system.GPU().Maxwell3D().dirty.flags; const bool is_dirty = flags[id]; @@ -72,7 +73,7 @@ private: } Core::System& system; - Flags invalidation_flags; + Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags; }; } // namespace Vulkan -- cgit v1.2.3 From 6669b359a3857c265bd4d1ed77c1bce6bcd6a912 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 01:21:57 -0300 Subject: vk_rasterizer: Pass Maxwell registers to dynamic updates --- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 35 ++++++++++-------------- src/video_core/renderer_vulkan/vk_rasterizer.h | 12 ++++---- 2 files changed, 21 insertions(+), 26 deletions(-) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index eb9c49d5e..02027b7d5 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -726,13 +726,13 @@ void RasterizerVulkan::SetupImageTransitions( } void RasterizerVulkan::UpdateDynamicStates() { - auto& gpu = system.GPU().Maxwell3D(); - UpdateViewportsState(gpu); - UpdateScissorsState(gpu); - UpdateDepthBias(gpu); - UpdateBlendConstants(gpu); - UpdateDepthBounds(gpu); - UpdateStencilFaces(gpu); + auto& regs = system.GPU().Maxwell3D().regs; + UpdateViewportsState(regs); + UpdateScissorsState(regs); + UpdateDepthBias(regs); + UpdateBlendConstants(regs); + UpdateDepthBounds(regs); + UpdateStencilFaces(regs); } void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex_input, @@ -978,11 +978,10 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima image_views.push_back(ImageView{std::move(view), image_layout}); } -void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { +void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchViewports()) { return; } - const auto& regs = gpu.regs; const std::array viewports{ GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), GetViewportState(device, regs, 2), GetViewportState(device, regs, 3), @@ -997,11 +996,10 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { }); } -void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { +void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchScissors()) { return; } - const auto& regs = gpu.regs; const std::array scissors = { GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), GetScissorState(regs, 3), GetScissorState(regs, 4), GetScissorState(regs, 5), @@ -1014,42 +1012,39 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { }); } -void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { +void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchDepthBias()) { return; } - const auto& regs = gpu.regs; scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, factor = regs.polygon_offset_factor](auto cmdbuf, auto& dld) { cmdbuf.setDepthBias(constant, clamp, factor / 2.0f, dld); }); } -void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { +void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchBlendConstants()) { return; } - const std::array blend_color = {gpu.regs.blend_color.r, gpu.regs.blend_color.g, - gpu.regs.blend_color.b, gpu.regs.blend_color.a}; + const std::array blend_color = {regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, + regs.blend_color.a}; scheduler.Record([blend_color](auto cmdbuf, auto& dld) { cmdbuf.setBlendConstants(blend_color.data(), dld); }); } -void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu) { +void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchDepthBounds()) { return; } - const auto& regs = gpu.regs; scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( auto cmdbuf, auto& dld) { cmdbuf.setDepthBounds(min, max, dld); }); } -void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu) { +void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs) { if (!state_tracker.TouchStencilProperties()) { return; } - const auto& regs = gpu.regs; if (regs.stencil_two_side_enable) { // Separate values per face scheduler.Record( diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index a79440eba..96ea05f0a 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -217,12 +217,12 @@ private: void SetupImage(const Tegra::Texture::TICEntry& tic, const ImageEntry& entry); - void UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu); - void UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu); - void UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu); - void UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu); - void UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu); - void UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu); + void UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& regs); + void UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs); + void UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs); + void UpdateBlendConstants(Tegra::Engines::Maxwell3D::Regs& regs); + void UpdateDepthBounds(Tegra::Engines::Maxwell3D::Regs& regs); + void UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs); std::size_t CalculateGraphicsStreamBufferSize(bool is_indexed) const; -- cgit v1.2.3 From ac204754d4fe2aaae214025d8f1f40bcb938d74f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 01:56:00 -0300 Subject: dirty_flags: Deduplicate code between OpenGL and Vulkan --- .../renderer_vulkan/vk_state_tracker.cpp | 41 ++-------------------- 1 file changed, 2 insertions(+), 39 deletions(-) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index 67229ffcc..d74e68b63 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp @@ -8,6 +8,7 @@ #include "common/common_types.h" #include "core/core.h" +#include "video_core/dirty_flags.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/gpu.h" #include "video_core/renderer_vulkan/vk_state_tracker.h" @@ -38,39 +39,6 @@ Flags MakeInvalidationFlags() { return flags; } -template -void FillBlock(Table& table, std::size_t begin, std::size_t num, Integer dirty_index) { - const auto it = std::begin(table) + begin; - std::fill(it, it + num, static_cast(dirty_index)); -} - -template -void FillBlock(Tables& tables, std::size_t begin, std::size_t num, Integer1 index_a, - Integer2 index_b) { - FillBlock(tables[0], begin, num, index_a); - FillBlock(tables[1], begin, num, index_b); -} - -void SetupDirtyRenderTargets(Tables& tables) { - static constexpr std::size_t num_per_rt = NUM(rt[0]); - static constexpr std::size_t begin = OFF(rt); - static constexpr std::size_t num = num_per_rt * Regs::NumRenderTargets; - for (std::size_t rt = 0; rt < Regs::NumRenderTargets; ++rt) { - FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt); - } - FillBlock(tables[1], begin, num, RenderTargets); - - static constexpr std::array zeta_flags{ZetaBuffer, RenderTargets}; - for (std::size_t i = 0; i < std::size(zeta_flags); ++i) { - const u8 flag = zeta_flags[i]; - auto& table = tables[i]; - table[OFF(zeta_enable)] = flag; - table[OFF(zeta_width)] = flag; - table[OFF(zeta_height)] = flag; - FillBlock(table, OFF(zeta), NUM(zeta), flag); - } -} - void SetupDirtyViewports(Tables& tables) { FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); @@ -123,12 +91,7 @@ void StateTracker::Initialize() { SetupDirtyDepthBounds(tables); SetupDirtyStencilProperties(tables); - auto& store = dirty.on_write_stores; - store[RenderTargets] = true; - store[ZetaBuffer] = true; - for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) { - store[ColorBuffer0 + i] = true; - } + SetupCommonOnWriteStores(dirty.on_write_stores); } void StateTracker::InvalidateCommandBufferState() { -- cgit v1.2.3