2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

vk_pipeline_cache: Add asynchronous shaders

This commit is contained in:
ReinUsesLisp 2021-06-05 22:10:02 -03:00 committed by ameerj
parent 2a0aeaa3d2
commit 48aad8dc05
3 changed files with 33 additions and 3 deletions

View file

@ -87,7 +87,7 @@ public:
configure_func(this, is_indexed); configure_func(this, is_indexed);
} }
GraphicsPipeline* Next(const GraphicsPipelineCacheKey& current_key) noexcept { [[nodiscard]] GraphicsPipeline* Next(const GraphicsPipelineCacheKey& current_key) noexcept {
if (key == current_key) { if (key == current_key) {
return this; return this;
} }
@ -96,6 +96,10 @@ public:
: nullptr; : nullptr;
} }
[[nodiscard]] bool IsBuilt() const noexcept {
return is_built.load(std::memory_order::relaxed);
}
template <typename Spec> template <typename Spec>
static auto MakeConfigureSpecFunc() { static auto MakeConfigureSpecFunc() {
return [](GraphicsPipeline* pipeline, bool is_indexed) { return [](GraphicsPipeline* pipeline, bool is_indexed) {

View file

@ -240,6 +240,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw
device{device_}, scheduler{scheduler_}, descriptor_pool{descriptor_pool_}, device{device_}, scheduler{scheduler_}, descriptor_pool{descriptor_pool_},
update_descriptor_queue{update_descriptor_queue_}, render_pass_cache{render_pass_cache_}, update_descriptor_queue{update_descriptor_queue_}, render_pass_cache{render_pass_cache_},
buffer_cache{buffer_cache_}, texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, texture_cache{texture_cache_},
use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()},
workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:PipelineBuilder"), workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:PipelineBuilder"),
serialization_thread(1, "yuzu:PipelineSerialization") { serialization_thread(1, "yuzu:PipelineSerialization") {
const auto& float_control{device.FloatControlProperties()}; const auto& float_control{device.FloatControlProperties()};
@ -303,7 +304,7 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() {
GraphicsPipeline* const next{current_pipeline->Next(graphics_key)}; GraphicsPipeline* const next{current_pipeline->Next(graphics_key)};
if (next) { if (next) {
current_pipeline = next; current_pipeline = next;
return current_pipeline; return BuiltPipeline(current_pipeline);
} }
} }
const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)}; const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
@ -318,7 +319,7 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() {
current_pipeline->AddTransition(pipeline.get()); current_pipeline->AddTransition(pipeline.get());
} }
current_pipeline = pipeline.get(); current_pipeline = pipeline.get();
return current_pipeline; return BuiltPipeline(current_pipeline);
} }
ComputePipeline* PipelineCache::CurrentComputePipeline() { ComputePipeline* PipelineCache::CurrentComputePipeline() {
@ -415,6 +416,27 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
workers.WaitForRequests(); workers.WaitForRequests();
} }
GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const noexcept {
if (pipeline->IsBuilt()) {
return pipeline;
}
if (!use_asynchronous_shaders) {
return pipeline;
}
// If something is using depth, we can assume that games are not rendering anything which
// will be used one time.
if (maxwell3d.regs.zeta_enable) {
return nullptr;
}
// If games are using a small index count, we can assume these are full screen quads.
// Usually these shaders are only used once for building textures so we can assume they
// can't be built async
if (maxwell3d.regs.index_array.count <= 6 || maxwell3d.regs.vertex_buffer.count <= 6) {
return pipeline;
}
return nullptr;
}
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
ShaderPools& pools, const GraphicsPipelineCacheKey& key, ShaderPools& pools, const GraphicsPipelineCacheKey& key,
std::span<Shader::Environment* const> envs, bool build_in_parallel) try { std::span<Shader::Environment* const> envs, bool build_in_parallel) try {

View file

@ -115,6 +115,8 @@ public:
const VideoCore::DiskResourceLoadCallback& callback); const VideoCore::DiskResourceLoadCallback& callback);
private: private:
[[nodiscard]] GraphicsPipeline* BuiltPipeline(GraphicsPipeline* pipeline) const noexcept;
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(); std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline();
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline( std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
@ -140,6 +142,8 @@ private:
GraphicsPipelineCacheKey graphics_key{}; GraphicsPipelineCacheKey graphics_key{};
GraphicsPipeline* current_pipeline{}; GraphicsPipeline* current_pipeline{};
bool use_asynchronous_shaders{};
std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache; std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache;
std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache; std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;