From 7ed5a0beea73aa7b283fc1ff52b94e99b9a8356f Mon Sep 17 00:00:00 2001 From: boykopovar Date: Fri, 25 Sep 2026 08:25:59 +0300 Subject: [PATCH] perf(agc): optimize pipeline cache key construction --- .../include/GraphicsPipelineCache.hpp | 5 +++-- .../Graphics/src/GraphicsPipelineCache.cpp | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/GraphicsPipelineCache.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/GraphicsPipelineCache.hpp index 47e999cd6..17299f660 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/include/GraphicsPipelineCache.hpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/GraphicsPipelineCache.hpp @@ -5,6 +5,7 @@ #include "prx/libSceAgcDriver/Graphics/include/RenderCache.hpp" #include #include +#include namespace AgcDriver::Graphics { @@ -15,13 +16,13 @@ public: private: struct Entry { - std::vector key; + std::string key; std::shared_ptr target; std::shared_ptr pipeline; }; Context context; std::list entries; - std::map, std::list::iterator> lookup; + std::map::iterator> lookup; }; } diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/GraphicsPipelineCache.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/GraphicsPipelineCache.cpp index a57717c7b..7414c171c 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/GraphicsPipelineCache.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/GraphicsPipelineCache.cpp @@ -9,14 +9,14 @@ namespace AgcDriver::Graphics { namespace { template -void append(std::vector& key, const TValue& value) { +void append(std::string& key, const TValue& value) { static_assert(std::is_trivially_copyable_v); - const auto bytes = std::as_bytes(std::span(&value, 1)); - key.insert(key.end(), bytes.begin(), bytes.end()); + key.append(reinterpret_cast(&value), sizeof(value)); } -std::vector makeKey(const Context& context, const State& state, const std::shared_ptr& target, const ShaderResources& resources, std::span shaders) { - std::vector key; +std::string makeKey(const Context& context, const State& state, const std::shared_ptr& target, const ShaderResources& resources, std::span shaders) { + PerformanceTimer timing("Graphics.PipelineKey"); + std::string key; key.reserve(512); append(key, target ? target->Target().View() : VK_NULL_HANDLE); append(key, state.hasColorTarget); @@ -67,7 +67,9 @@ std::vector makeKey(const Context& context, const State& state, const append(key, tessellation.partitioning); append(key, tessellation.outputTopology); } + timing.Mark("state"); const auto input = BuildVertexInputLayout(context, shaders.front().program->vertexAttributes); + timing.Mark("vertex_layout"); append(key, input.bindings.size()); for (const auto& binding : input.bindings) { append(key, binding.binding); @@ -82,15 +84,20 @@ std::vector makeKey(const Context& context, const State& state, const append(key, attribute.offset); } append(key, resources.LayoutKey().size()); - for (const auto value : resources.LayoutKey()) append(key, value); + const auto layout = std::span(resources.LayoutKey()); + if (!layout.empty()) key.append(reinterpret_cast(layout.data()), layout.size_bytes()); append(key, PushConstantStages(shaders)); append(key, shaders.size()); + timing.Mark("resources"); + std::uint64_t shaderBytes = 0; for (const auto& shader : shaders) { append(key, shader.stage); append(key, shader.program->spirv.size()); const auto bytes = std::as_bytes(std::span(shader.program->spirv)); - key.insert(key.end(), bytes.begin(), bytes.end()); + if (!bytes.empty()) key.append(reinterpret_cast(bytes.data()), bytes.size()); + shaderBytes += bytes.size(); } + timing.Mark("shader_code", shaderBytes); return key; }