From a2285669b38fc9f891a48dee10bab5b5a584f6e6 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Tue, 11 Jan 2022 20:01:54 +0530 Subject: [PATCH] Use static vector for shader bytecode to prevent constant reallocation Using `std::vector` for shader bytecode led to a lot of reallocation due to constant resizing, switching over the static vector allows for a single static allocation of the maximum possible guest shader size (1 MiB) to be done for every stage resulting in a 6 MiB preallocation which is unnoticeable given the total memory overhead of running a Switch application. --- .../main/cpp/skyline/common/address_space.h | 4 +-- .../gpu/interconnect/graphics_context.h | 36 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/app/src/main/cpp/skyline/common/address_space.h b/app/src/main/cpp/skyline/common/address_space.h index a7a99a76..23780d48 100644 --- a/app/src/main/cpp/skyline/common/address_space.h +++ b/app/src/main/cpp/skyline/common/address_space.h @@ -138,8 +138,8 @@ namespace skyline { * @return If returning was caused by the supplied function returning a non-nullopt value or other conditions * @note The function will **NOT** be run on any sparse block */ - template - bool ReadTill(std::vector& destination, VaType virt, Function function) { + template + bool ReadTill(Container& destination, VaType virt, Function function) { //TRACE_EVENT("containers", "FlatMemoryManager::ReadTill"); std::scoped_lock lock(this->blockMutex); diff --git a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h index a999e7a5..1eb1fc59 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -618,6 +618,8 @@ namespace skyline::gpu::interconnect { /* Shader Program */ private: + constexpr static size_t MaxShaderBytecodeSize{1 * 1024 * 1024}; //!< The largest shader binary that we support (1 MiB) + struct Shader { bool enabled{false}; ShaderCompiler::Stage stage; @@ -625,7 +627,7 @@ namespace skyline::gpu::interconnect { bool invalidated{true}; //!< If the shader that existed earlier has been invalidated bool shouldCheckSame{false}; //!< If we should do a check for the shader being the same as before u32 offset{}; //!< Offset of the shader from the base IOVA - std::vector data; //!< The shader bytecode in a vector + boost::container::static_vector data; //!< The shader bytecode in a statically allocated vector std::optional program; Shader(ShaderCompiler::Stage stage) : stage(stage) {} @@ -657,14 +659,14 @@ namespace skyline::gpu::interconnect { }; struct ShaderSet : public std::array { - ShaderSet() : array({ - Shader{ShaderCompiler::Stage::VertexA}, - Shader{ShaderCompiler::Stage::VertexB}, - Shader{ShaderCompiler::Stage::TessellationControl}, - Shader{ShaderCompiler::Stage::TessellationEval}, - Shader{ShaderCompiler::Stage::Geometry}, - Shader{ShaderCompiler::Stage::Fragment}, - }) {} + ShaderSet() : array{ + Shader{ShaderCompiler::Stage::VertexA}, + Shader{ShaderCompiler::Stage::VertexB}, + Shader{ShaderCompiler::Stage::TessellationControl}, + Shader{ShaderCompiler::Stage::TessellationEval}, + Shader{ShaderCompiler::Stage::Geometry}, + Shader{ShaderCompiler::Stage::Fragment}, + } {} Shader &at(maxwell3d::ShaderStage stage) { return array::at(static_cast(stage)); @@ -692,13 +694,13 @@ namespace skyline::gpu::interconnect { }; struct PipelineStages : public std::array { - PipelineStages() : array({ - PipelineStage{vk::ShaderStageFlagBits::eVertex}, - PipelineStage{vk::ShaderStageFlagBits::eTessellationControl}, - PipelineStage{vk::ShaderStageFlagBits::eTessellationEvaluation}, - PipelineStage{vk::ShaderStageFlagBits::eGeometry}, - PipelineStage{vk::ShaderStageFlagBits::eFragment}, - }) {} + PipelineStages() : array{ + PipelineStage{vk::ShaderStageFlagBits::eVertex}, + PipelineStage{vk::ShaderStageFlagBits::eTessellationControl}, + PipelineStage{vk::ShaderStageFlagBits::eTessellationEvaluation}, + PipelineStage{vk::ShaderStageFlagBits::eGeometry}, + PipelineStage{vk::ShaderStageFlagBits::eFragment}, + } {} PipelineStage &at(maxwell3d::PipelineStage stage) { return array::at(static_cast(stage)); @@ -715,8 +717,6 @@ namespace skyline::gpu::interconnect { ShaderCompiler::RuntimeInfo runtimeInfo{}; - constexpr static size_t MaxShaderBytecodeSize{1 * 1024 * 1024}; //!< The largest shader binary that we support (1 MiB) - constexpr static size_t PipelineUniqueDescriptorTypeCount{2}; //!< The amount of unique descriptor types that may be bound to a pipeline constexpr static size_t MaxPipelineDescriptorWriteCount{maxwell3d::PipelineStageCount * PipelineUniqueDescriptorTypeCount}; //!< The maxium amount of descriptors writes that are used to bind a pipeline constexpr static size_t MaxPipelineDescriptorCount{100}; //!< The maxium amount of descriptors we support being bound to a pipeline