mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-22 15:48:56 +00:00
[TEST] Adjustments on the pipeline cache + optimized vertex buffer refinement
This commit is contained in:
@@ -811,7 +811,7 @@ void BufferCache<P>::BindHostVertexBuffers() {
|
||||
if (use_optimized_vertex_buffers) {
|
||||
auto& flags = maxwell3d->dirty.flags;
|
||||
const u32 enabled_mask = enabled_vertex_buffers_mask;
|
||||
bool any_dirty = false;
|
||||
u32 dirty_mask = 0;
|
||||
u32 pending_mask = enabled_mask;
|
||||
while (pending_mask != 0) {
|
||||
const u32 index = std::countr_zero(pending_mask);
|
||||
@@ -820,13 +820,15 @@ void BufferCache<P>::BindHostVertexBuffers() {
|
||||
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||
TouchBuffer(buffer, binding.buffer_id);
|
||||
SynchronizeBuffer(buffer, binding.device_addr, binding.size);
|
||||
any_dirty |= flags[Dirty::VertexBuffer0 + index];
|
||||
if (flags[Dirty::VertexBuffer0 + index]) {
|
||||
dirty_mask |= 1u << index;
|
||||
}
|
||||
}
|
||||
if (enabled_mask == 0 || !any_dirty) {
|
||||
if (dirty_mask == 0) {
|
||||
return;
|
||||
}
|
||||
const u32 min_index = static_cast<u32>(std::countr_zero(enabled_mask));
|
||||
const u32 max_index = 32u - static_cast<u32>(std::countl_zero(enabled_mask));
|
||||
const u32 min_index = static_cast<u32>(std::countr_zero(dirty_mask));
|
||||
const u32 max_index = 32u - static_cast<u32>(std::countl_zero(dirty_mask));
|
||||
HostBindings<Buffer> bindings{};
|
||||
bindings.min_index = min_index;
|
||||
bindings.max_index = max_index;
|
||||
|
||||
@@ -32,6 +32,7 @@ using Shader::Backend::SPIRV::RESCALING_LAYOUT_WORDS_OFFSET;
|
||||
using Tegra::Texture::TexturePair;
|
||||
|
||||
ComputePipeline::ComputePipeline(const Device& device_, Scheduler& scheduler, vk::PipelineCache& pipeline_cache_,
|
||||
std::shared_mutex& pipeline_cache_mutex_,
|
||||
DescriptorPool& descriptor_pool,
|
||||
GuestDescriptorQueue& guest_descriptor_queue_,
|
||||
DescriptorBufferRing& descriptor_buffer_ring_,
|
||||
@@ -40,7 +41,8 @@ ComputePipeline::ComputePipeline(const Device& device_, Scheduler& scheduler, vk
|
||||
VideoCore::ShaderNotify* shader_notify, const Shader::Info& info_,
|
||||
vk::ShaderModule spv_module_, u64 shader_hash_)
|
||||
: device{device_},
|
||||
pipeline_cache(pipeline_cache_), guest_descriptor_queue{guest_descriptor_queue_},
|
||||
pipeline_cache(pipeline_cache_), pipeline_cache_mutex(pipeline_cache_mutex_),
|
||||
guest_descriptor_queue{guest_descriptor_queue_},
|
||||
descriptor_buffer_ring{descriptor_buffer_ring_}, info{info_},
|
||||
shader_hash{shader_hash_}, spv_module(std::move(spv_module_)) {
|
||||
if (shader_notify) {
|
||||
@@ -111,6 +113,7 @@ ComputePipeline::ComputePipeline(const Device& device_, Scheduler& scheduler, vk
|
||||
.basePipelineIndex = 0,
|
||||
};
|
||||
try {
|
||||
std::shared_lock cache_lock{pipeline_cache_mutex};
|
||||
pipeline = device.GetLogical().CreateComputePipeline(compute_ci, *pipeline_cache);
|
||||
} catch (const vk::Exception& exception) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Adreno rejected compute shader {:016X}: {}", shader_hash,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/thread_worker.h"
|
||||
@@ -34,6 +35,7 @@ class Scheduler;
|
||||
class ComputePipeline {
|
||||
public:
|
||||
explicit ComputePipeline(const Device& device, Scheduler& scheduler, vk::PipelineCache& pipeline_cache,
|
||||
std::shared_mutex& pipeline_cache_mutex,
|
||||
DescriptorPool& descriptor_pool,
|
||||
GuestDescriptorQueue& guest_descriptor_queue,
|
||||
DescriptorBufferRing& descriptor_buffer_ring,
|
||||
@@ -59,6 +61,7 @@ public:
|
||||
private:
|
||||
const Device& device;
|
||||
vk::PipelineCache& pipeline_cache;
|
||||
std::shared_mutex& pipeline_cache_mutex;
|
||||
GuestDescriptorQueue& guest_descriptor_queue;
|
||||
DescriptorBufferRing& descriptor_buffer_ring;
|
||||
Shader::Info info;
|
||||
|
||||
@@ -251,7 +251,8 @@ ConfigureFuncPtr ConfigureFunc(const std::array<vk::ShaderModule, NUM_STAGES>& m
|
||||
// TODO(crueter): This is the worst-formatted code I have EVER seen
|
||||
GraphicsPipeline::GraphicsPipeline(
|
||||
Scheduler& scheduler_, BufferCache& buffer_cache_, TextureCache& texture_cache_,
|
||||
vk::PipelineCache& pipeline_cache_, VideoCore::ShaderNotify* shader_notify,
|
||||
vk::PipelineCache& pipeline_cache_, std::shared_mutex& pipeline_cache_mutex_,
|
||||
VideoCore::ShaderNotify* shader_notify,
|
||||
const Device& device_, DescriptorPool& descriptor_pool,
|
||||
GuestDescriptorQueue& guest_descriptor_queue_, DescriptorBufferRing& descriptor_buffer_ring_,
|
||||
Common::ThreadWorker* worker_thread,
|
||||
@@ -259,7 +260,8 @@ GraphicsPipeline::GraphicsPipeline(
|
||||
const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages,
|
||||
const std::array<const Shader::Info*, NUM_STAGES>& infos)
|
||||
: key{key_}, device{device_}, texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
|
||||
pipeline_cache(pipeline_cache_), scheduler{scheduler_},
|
||||
pipeline_cache(pipeline_cache_), pipeline_cache_mutex(pipeline_cache_mutex_),
|
||||
scheduler{scheduler_},
|
||||
guest_descriptor_queue{guest_descriptor_queue_},
|
||||
descriptor_buffer_ring{descriptor_buffer_ring_}, spv_modules{std::move(stages)} {
|
||||
if (shader_notify) {
|
||||
@@ -1081,6 +1083,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
||||
flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
|
||||
}
|
||||
|
||||
std::shared_lock cache_lock{pipeline_cache_mutex};
|
||||
pipeline = device.GetLogical().CreateGraphicsPipeline({
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -78,7 +79,8 @@ class GraphicsPipeline {
|
||||
public:
|
||||
explicit GraphicsPipeline(
|
||||
Scheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache,
|
||||
vk::PipelineCache& pipeline_cache, VideoCore::ShaderNotify* shader_notify,
|
||||
vk::PipelineCache& pipeline_cache, std::shared_mutex& pipeline_cache_mutex,
|
||||
VideoCore::ShaderNotify* shader_notify,
|
||||
const Device& device, DescriptorPool& descriptor_pool,
|
||||
GuestDescriptorQueue& guest_descriptor_queue,
|
||||
DescriptorBufferRing& descriptor_buffer_ring, Common::ThreadWorker* worker_thread,
|
||||
@@ -151,6 +153,7 @@ private:
|
||||
TextureCache& texture_cache;
|
||||
BufferCache& buffer_cache;
|
||||
vk::PipelineCache& pipeline_cache;
|
||||
std::shared_mutex& pipeline_cache_mutex;
|
||||
Scheduler& scheduler;
|
||||
GuestDescriptorQueue& guest_descriptor_queue;
|
||||
DescriptorBufferRing& descriptor_buffer_ring;
|
||||
|
||||
@@ -553,6 +553,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
|
||||
PipelineCache::~PipelineCache() {
|
||||
if (use_vulkan_pipeline_cache && !vulkan_pipeline_cache_filename.empty()) {
|
||||
std::unique_lock lock{vulkan_pipeline_cache_mutex};
|
||||
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache,
|
||||
CACHE_VERSION);
|
||||
}
|
||||
@@ -612,6 +613,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
|
||||
|
||||
if (use_vulkan_pipeline_cache) {
|
||||
vulkan_pipeline_cache_filename = base_dir / "vulkan_pipelines.bin";
|
||||
std::unique_lock lock{vulkan_pipeline_cache_mutex};
|
||||
vulkan_pipeline_cache =
|
||||
LoadVulkanPipelineCache(vulkan_pipeline_cache_filename, CACHE_VERSION);
|
||||
}
|
||||
@@ -710,6 +712,7 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
|
||||
workers.WaitForRequests(stop_loading);
|
||||
|
||||
if (use_vulkan_pipeline_cache) {
|
||||
std::unique_lock lock{vulkan_pipeline_cache_mutex};
|
||||
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache,
|
||||
CACHE_VERSION);
|
||||
size_t size = 0;
|
||||
@@ -743,11 +746,14 @@ void PipelineCache::QueueVulkanPipelineCacheFlush() {
|
||||
pipelines_since_flush = 0;
|
||||
last_flush = now;
|
||||
serialization_thread.QueueWork([this] {
|
||||
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache,
|
||||
CACHE_VERSION);
|
||||
size_t size = 0;
|
||||
vulkan_pipeline_cache.Read(&size, nullptr);
|
||||
last_cache_size.store(size, std::memory_order_relaxed);
|
||||
{
|
||||
std::unique_lock lock{vulkan_pipeline_cache_mutex};
|
||||
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache,
|
||||
CACHE_VERSION);
|
||||
size_t size = 0;
|
||||
vulkan_pipeline_cache.Read(&size, nullptr);
|
||||
last_cache_size.store(size, std::memory_order_relaxed);
|
||||
}
|
||||
flush_in_flight.store(false, std::memory_order_release);
|
||||
});
|
||||
}
|
||||
@@ -890,7 +896,8 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||
}
|
||||
Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr};
|
||||
return std::make_unique<GraphicsPipeline>(
|
||||
scheduler, buffer_cache, texture_cache, vulkan_pipeline_cache, &shader_notify, device,
|
||||
scheduler, buffer_cache, texture_cache, vulkan_pipeline_cache,
|
||||
vulkan_pipeline_cache_mutex, &shader_notify, device,
|
||||
descriptor_pool, guest_descriptor_queue, descriptor_buffer_ring, thread_worker, statistics,
|
||||
render_pass_cache, key, std::move(modules), infos);
|
||||
|
||||
@@ -1014,7 +1021,8 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
||||
spv_module.SetObjectNameEXT(name.c_str());
|
||||
}
|
||||
Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr};
|
||||
return std::make_unique<ComputePipeline>(device, scheduler, vulkan_pipeline_cache, descriptor_pool,
|
||||
return std::make_unique<ComputePipeline>(device, scheduler, vulkan_pipeline_cache,
|
||||
vulkan_pipeline_cache_mutex, descriptor_pool,
|
||||
guest_descriptor_queue, descriptor_buffer_ring,
|
||||
thread_worker, statistics,
|
||||
&shader_notify, program.info, std::move(spv_module),
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <type_traits>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <vector>
|
||||
@@ -175,6 +177,7 @@ private:
|
||||
|
||||
std::filesystem::path vulkan_pipeline_cache_filename;
|
||||
vk::PipelineCache vulkan_pipeline_cache;
|
||||
std::shared_mutex vulkan_pipeline_cache_mutex;
|
||||
size_t pipelines_since_flush{};
|
||||
std::chrono::steady_clock::time_point last_flush{};
|
||||
std::atomic<size_t> last_cache_size{};
|
||||
|
||||
Reference in New Issue
Block a user