mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-23 17:00:57 +01:00
vk_state_tracker: Initial implementation
Add support for render targets and viewports.
This commit is contained in:
parent
b1498d2c54
commit
1bd95a314f
10 changed files with 198 additions and 52 deletions
|
@ -199,6 +199,8 @@ if (ENABLE_VULKAN)
|
||||||
renderer_vulkan/vk_shader_util.h
|
renderer_vulkan/vk_shader_util.h
|
||||||
renderer_vulkan/vk_staging_buffer_pool.cpp
|
renderer_vulkan/vk_staging_buffer_pool.cpp
|
||||||
renderer_vulkan/vk_staging_buffer_pool.h
|
renderer_vulkan/vk_staging_buffer_pool.h
|
||||||
|
renderer_vulkan/vk_state_tracker.cpp
|
||||||
|
renderer_vulkan/vk_state_tracker.h
|
||||||
renderer_vulkan/vk_stream_buffer.cpp
|
renderer_vulkan/vk_stream_buffer.cpp
|
||||||
renderer_vulkan/vk_stream_buffer.h
|
renderer_vulkan/vk_stream_buffer.h
|
||||||
renderer_vulkan/vk_swapchain.cpp
|
renderer_vulkan/vk_swapchain.cpp
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
#include "video_core/renderer_vulkan/vk_rasterizer.h"
|
||||||
#include "video_core/renderer_vulkan/vk_resource_manager.h"
|
#include "video_core/renderer_vulkan/vk_resource_manager.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.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"
|
#include "video_core/renderer_vulkan/vk_swapchain.h"
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
@ -177,10 +178,13 @@ bool RendererVulkan::Init() {
|
||||||
swapchain = std::make_unique<VKSwapchain>(surface, *device);
|
swapchain = std::make_unique<VKSwapchain>(surface, *device);
|
||||||
swapchain->Create(framebuffer.width, framebuffer.height, false);
|
swapchain->Create(framebuffer.width, framebuffer.height, false);
|
||||||
|
|
||||||
scheduler = std::make_unique<VKScheduler>(*device, *resource_manager);
|
state_tracker = std::make_unique<StateTracker>(system);
|
||||||
|
|
||||||
|
scheduler = std::make_unique<VKScheduler>(*device, *resource_manager, *state_tracker);
|
||||||
|
|
||||||
rasterizer = std::make_unique<RasterizerVulkan>(system, render_window, screen_info, *device,
|
rasterizer = std::make_unique<RasterizerVulkan>(system, render_window, screen_info, *device,
|
||||||
*resource_manager, *memory_manager, *scheduler);
|
*resource_manager, *memory_manager,
|
||||||
|
*state_tracker, *scheduler);
|
||||||
|
|
||||||
blit_screen = std::make_unique<VKBlitScreen>(system, render_window, *rasterizer, *device,
|
blit_screen = std::make_unique<VKBlitScreen>(system, render_window, *rasterizer, *device,
|
||||||
*resource_manager, *memory_manager, *swapchain,
|
*resource_manager, *memory_manager, *swapchain,
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/renderer_vulkan/declarations.h"
|
#include "video_core/renderer_vulkan/declarations.h"
|
||||||
|
|
||||||
|
@ -15,6 +17,7 @@ class System;
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
|
class StateTracker;
|
||||||
class VKBlitScreen;
|
class VKBlitScreen;
|
||||||
class VKDevice;
|
class VKDevice;
|
||||||
class VKFence;
|
class VKFence;
|
||||||
|
@ -61,6 +64,7 @@ private:
|
||||||
std::unique_ptr<VKSwapchain> swapchain;
|
std::unique_ptr<VKSwapchain> swapchain;
|
||||||
std::unique_ptr<VKMemoryManager> memory_manager;
|
std::unique_ptr<VKMemoryManager> memory_manager;
|
||||||
std::unique_ptr<VKResourceManager> resource_manager;
|
std::unique_ptr<VKResourceManager> resource_manager;
|
||||||
|
std::unique_ptr<StateTracker> state_tracker;
|
||||||
std::unique_ptr<VKScheduler> scheduler;
|
std::unique_ptr<VKScheduler> scheduler;
|
||||||
std::unique_ptr<VKBlitScreen> blit_screen;
|
std::unique_ptr<VKBlitScreen> blit_screen;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "video_core/renderer_vulkan/vk_sampler_cache.h"
|
#include "video_core/renderer_vulkan/vk_sampler_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.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_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_texture_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_update_descriptor.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,
|
RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer,
|
||||||
VKScreenInfo& screen_info, const VKDevice& device,
|
VKScreenInfo& screen_info, const VKDevice& device,
|
||||||
VKResourceManager& resource_manager,
|
VKResourceManager& resource_manager,
|
||||||
VKMemoryManager& memory_manager, VKScheduler& scheduler)
|
VKMemoryManager& memory_manager, StateTracker& state_tracker,
|
||||||
|
VKScheduler& scheduler)
|
||||||
: RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer},
|
: RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer},
|
||||||
screen_info{screen_info}, device{device}, resource_manager{resource_manager},
|
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),
|
staging_pool(device, memory_manager, scheduler), descriptor_pool(device),
|
||||||
update_descriptor_queue(device, scheduler),
|
update_descriptor_queue(device, scheduler),
|
||||||
quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerVulkan::SetupDirtyFlags() {
|
||||||
|
state_tracker.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::FlushWork() {
|
void RasterizerVulkan::FlushWork() {
|
||||||
static constexpr u32 DRAWS_TO_DISPATCH = 4096;
|
static constexpr u32 DRAWS_TO_DISPATCH = 4096;
|
||||||
|
|
||||||
|
@ -568,7 +574,9 @@ void RasterizerVulkan::FlushWork() {
|
||||||
|
|
||||||
RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() {
|
RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() {
|
||||||
MICROPROFILE_SCOPE(Vulkan_RenderTargets);
|
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);
|
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) {
|
void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) {
|
||||||
|
if (!state_tracker.TouchViewports()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto& regs = gpu.regs;
|
const auto& regs = gpu.regs;
|
||||||
const std::array viewports{
|
const std::array viewports{
|
||||||
GetViewportState(device, regs, 0), GetViewportState(device, regs, 1),
|
GetViewportState(device, regs, 0), GetViewportState(device, regs, 1),
|
||||||
|
|
|
@ -96,6 +96,7 @@ struct hash<Vulkan::FramebufferCacheKey> {
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
|
class StateTracker;
|
||||||
class BufferBindings;
|
class BufferBindings;
|
||||||
|
|
||||||
struct ImageView {
|
struct ImageView {
|
||||||
|
@ -108,7 +109,7 @@ public:
|
||||||
explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window,
|
explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window,
|
||||||
VKScreenInfo& screen_info, const VKDevice& device,
|
VKScreenInfo& screen_info, const VKDevice& device,
|
||||||
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
VKResourceManager& resource_manager, VKMemoryManager& memory_manager,
|
||||||
VKScheduler& scheduler);
|
StateTracker& state_tracker, VKScheduler& scheduler);
|
||||||
~RasterizerVulkan() override;
|
~RasterizerVulkan() override;
|
||||||
|
|
||||||
void Draw(bool is_indexed, bool is_instanced) override;
|
void Draw(bool is_indexed, bool is_instanced) override;
|
||||||
|
@ -127,6 +128,7 @@ public:
|
||||||
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
||||||
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
||||||
u32 pixel_stride) override;
|
u32 pixel_stride) override;
|
||||||
|
void SetupDirtyFlags() override;
|
||||||
|
|
||||||
/// Maximum supported size that a constbuffer can have in bytes.
|
/// Maximum supported size that a constbuffer can have in bytes.
|
||||||
static constexpr std::size_t MaxConstbufferSize = 0x10000;
|
static constexpr std::size_t MaxConstbufferSize = 0x10000;
|
||||||
|
@ -241,6 +243,7 @@ private:
|
||||||
const VKDevice& device;
|
const VKDevice& device;
|
||||||
VKResourceManager& resource_manager;
|
VKResourceManager& resource_manager;
|
||||||
VKMemoryManager& memory_manager;
|
VKMemoryManager& memory_manager;
|
||||||
|
StateTracker& state_tracker;
|
||||||
VKScheduler& scheduler;
|
VKScheduler& scheduler;
|
||||||
|
|
||||||
VKStagingBufferPool staging_pool;
|
VKStagingBufferPool staging_pool;
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "video_core/renderer_vulkan/declarations.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_query_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_resource_manager.h"
|
#include "video_core/renderer_vulkan/vk_resource_manager.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_state_tracker.h"
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
|
@ -29,9 +36,10 @@ void VKScheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf,
|
||||||
last = nullptr;
|
last = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager)
|
VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager,
|
||||||
: device{device}, resource_manager{resource_manager}, next_fence{
|
StateTracker& state_tracker)
|
||||||
&resource_manager.CommitFence()} {
|
: device{device}, resource_manager{resource_manager}, state_tracker{state_tracker},
|
||||||
|
next_fence{&resource_manager.CommitFence()} {
|
||||||
AcquireNewChunk();
|
AcquireNewChunk();
|
||||||
AllocateNewContext();
|
AllocateNewContext();
|
||||||
worker_thread = std::thread(&VKScheduler::WorkerThread, this);
|
worker_thread = std::thread(&VKScheduler::WorkerThread, this);
|
||||||
|
@ -157,12 +165,7 @@ void VKScheduler::AllocateNewContext() {
|
||||||
|
|
||||||
void VKScheduler::InvalidateState() {
|
void VKScheduler::InvalidateState() {
|
||||||
state.graphics_pipeline = nullptr;
|
state.graphics_pipeline = nullptr;
|
||||||
state.viewports = false;
|
state_tracker.InvalidateCommandBufferState();
|
||||||
state.scissors = false;
|
|
||||||
state.depth_bias = false;
|
|
||||||
state.blend_constants = false;
|
|
||||||
state.depth_bounds = false;
|
|
||||||
state.stencil_values = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKScheduler::EndPendingOperations() {
|
void VKScheduler::EndPendingOperations() {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
|
class StateTracker;
|
||||||
class VKDevice;
|
class VKDevice;
|
||||||
class VKFence;
|
class VKFence;
|
||||||
class VKQueryCache;
|
class VKQueryCache;
|
||||||
|
@ -43,7 +44,8 @@ private:
|
||||||
/// OpenGL-like operations on Vulkan command buffers.
|
/// OpenGL-like operations on Vulkan command buffers.
|
||||||
class VKScheduler {
|
class VKScheduler {
|
||||||
public:
|
public:
|
||||||
explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager);
|
explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager,
|
||||||
|
StateTracker& state_tracker);
|
||||||
~VKScheduler();
|
~VKScheduler();
|
||||||
|
|
||||||
/// Sends the current execution context to the GPU.
|
/// Sends the current execution context to the GPU.
|
||||||
|
@ -74,36 +76,6 @@ public:
|
||||||
query_cache = &query_cache_;
|
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.
|
/// Send work to a separate thread.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Record(T&& command) {
|
void Record(T&& command) {
|
||||||
|
@ -217,6 +189,8 @@ private:
|
||||||
|
|
||||||
const VKDevice& device;
|
const VKDevice& device;
|
||||||
VKResourceManager& resource_manager;
|
VKResourceManager& resource_manager;
|
||||||
|
StateTracker& state_tracker;
|
||||||
|
|
||||||
VKQueryCache* query_cache = nullptr;
|
VKQueryCache* query_cache = nullptr;
|
||||||
|
|
||||||
vk::CommandBuffer current_cmdbuf;
|
vk::CommandBuffer current_cmdbuf;
|
||||||
|
@ -226,12 +200,6 @@ private:
|
||||||
struct State {
|
struct State {
|
||||||
std::optional<vk::RenderPassBeginInfo> renderpass;
|
std::optional<vk::RenderPassBeginInfo> renderpass;
|
||||||
vk::Pipeline graphics_pipeline;
|
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;
|
} state;
|
||||||
|
|
||||||
std::unique_ptr<CommandChunk> chunk;
|
std::unique_ptr<CommandChunk> chunk;
|
||||||
|
|
97
src/video_core/renderer_vulkan/vk_state_tracker.cpp
Normal file
97
src/video_core/renderer_vulkan/vk_state_tracker.cpp
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#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<decltype(Maxwell3D::dirty)>;
|
||||||
|
using Tables = std::remove_reference_t<decltype(Maxwell3D::dirty.tables)>;
|
||||||
|
using Table = std::remove_reference_t<decltype(Maxwell3D::dirty.tables[0])>;
|
||||||
|
using Flags = std::remove_reference_t<decltype(Maxwell3D::dirty.flags)>;
|
||||||
|
|
||||||
|
Flags MakeInvalidationFlags() {
|
||||||
|
Flags flags{};
|
||||||
|
flags[Viewports] = true;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Integer>
|
||||||
|
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<u8>(dirty_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Integer1, typename Integer2>
|
||||||
|
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
|
53
src/video_core/renderer_vulkan/vk_state_tracker.h
Normal file
53
src/video_core/renderer_vulkan/vk_state_tracker.h
Normal file
|
@ -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 <type_traits> // REMOVE ME
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#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<decltype(Tegra::Engines::Maxwell3D::dirty.flags)>;
|
||||||
|
|
||||||
|
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
|
|
@ -22,6 +22,7 @@
|
||||||
#include "video_core/renderer_vulkan/vk_device.h"
|
#include "video_core/renderer_vulkan/vk_device.h"
|
||||||
#include "video_core/renderer_vulkan/vk_memory_manager.h"
|
#include "video_core/renderer_vulkan/vk_memory_manager.h"
|
||||||
#include "video_core/renderer_vulkan/vk_rasterizer.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_staging_buffer_pool.h"
|
||||||
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
||||||
#include "video_core/surface.h"
|
#include "video_core/surface.h"
|
||||||
|
|
Loading…
Reference in a new issue