Skip to content

Commit 5ca22bf

Browse files
committed
Add thread pool to VulkanPipelineCache
Also add callback manager. Instantiate, and add method for checking if prewarming is supported and enabled on the current device / instance.
1 parent 67aaf75 commit 5ca22bf

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

filament/backend/src/vulkan/VulkanDriver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, VulkanContext& context,
232232
mPlatform->getGraphicsQueueFamilyIndex(), mPlatform->getProtectedGraphicsQueue(),
233233
mPlatform->getProtectedGraphicsQueueFamilyIndex(), mContext, &mSemaphoreManager),
234234
mPipelineLayoutCache(mPlatform->getDevice()),
235-
mPipelineCache(mPlatform->getDevice(), mContext),
235+
mPipelineCache(*this, mPlatform->getDevice(), mContext),
236236
mStagePool(mAllocator, &mResourceManager, &mCommands, &mContext.getPhysicalDeviceLimits()),
237237
mBufferCache(mContext, mResourceManager, mAllocator),
238238
mFramebufferCache(mPlatform->getDevice()),

filament/backend/src/vulkan/VulkanPipelineCache.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "VulkanPipelineCache.h"
1818

19+
#include <utils/JobSystem.h>
1920
#include <utils/Log.h>
2021
#include <utils/Panic.h>
2122

@@ -36,6 +37,8 @@ namespace filament::backend {
3637

3738
namespace {
3839

40+
using utils::JobSystem;
41+
3942
#if FVK_ENABLED(FVK_DEBUG_SHADER_MODULE)
4043
void printPipelineFeedbackInfo(VkPipelineCreationFeedbackCreateInfo const& feedbackInfo) {
4144
VkPipelineCreationFeedback const& pipelineInfo = *feedbackInfo.pPipelineCreationFeedback;
@@ -66,13 +69,26 @@ void printPipelineFeedbackInfo(VkPipelineCreationFeedbackCreateInfo const& feedb
6669

6770
} // namespace
6871

69-
VulkanPipelineCache::VulkanPipelineCache(VkDevice device, VulkanContext const& context)
72+
VulkanPipelineCache::VulkanPipelineCache(DriverBase& driver, VkDevice device, VulkanContext const& context)
7073
: mDevice(device),
74+
mCallbackManager(driver),
7175
mContext(context) {
7276
VkPipelineCacheCreateInfo createInfo = {
7377
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
7478
};
7579
bluevk::vkCreatePipelineCache(mDevice, &createInfo, VKALLOC, &mPipelineCache);
80+
81+
if (isAsyncPrewarmingSupported(context)) {
82+
mCompilerThreadPool.init(
83+
/*threadCount=*/1,
84+
[]() {
85+
JobSystem::setThreadName("CompilerThreadPool");
86+
// This thread should be lower priority than the main thread.
87+
JobSystem::setThreadPriority(JobSystem::Priority::DISPLAY);
88+
}, []() {
89+
// No cleanup required.
90+
});
91+
}
7692
}
7793

7894
void VulkanPipelineCache::bindLayout(VkPipelineLayout layout) noexcept {
@@ -88,8 +104,8 @@ VulkanPipelineCache::PipelineCacheEntry* VulkanPipelineCache::getOrCreatePipelin
88104
return &pipeline;
89105
}
90106
PipelineCacheEntry cacheEntry {
91-
.lastUsed = mCurrentTime,
92107
.handle = createPipeline(mPipelineRequirements),
108+
.lastUsed = mCurrentTime,
93109
};
94110
return &mPipelines.emplace(mPipelineRequirements, cacheEntry).first.value();
95111
}

filament/backend/src/vulkan/VulkanPipelineCache.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#ifndef TNT_FILAMENT_BACKEND_VULKANPIPELINECACHE_H
1818
#define TNT_FILAMENT_BACKEND_VULKANPIPELINECACHE_H
1919

20+
#include "CallbackManager.h"
21+
#include "CompilerThreadPool.h"
2022
#include "VulkanCommands.h"
2123

2224
#include <backend/DriverEnums.h>
@@ -46,6 +48,12 @@ class VulkanPipelineCache {
4648
VulkanPipelineCache(VulkanPipelineCache const&) = delete;
4749
VulkanPipelineCache& operator=(VulkanPipelineCache const&) = delete;
4850

51+
static inline bool isAsyncPrewarmingSupported(VulkanContext const& context) {
52+
return context.asyncPipelineCachePrewarmingEnabled() &&
53+
context.isDynamicRenderingSupported() &&
54+
context.isVertexInputDynamicStateSupported();
55+
}
56+
4957
static constexpr uint32_t SHADER_MODULE_COUNT = 2;
5058
static constexpr uint32_t VERTEX_ATTRIBUTE_COUNT = MAX_VERTEX_ATTRIBUTE_COUNT;
5159

@@ -86,14 +94,21 @@ class VulkanPipelineCache {
8694

8795
static_assert(sizeof(RasterState) == 16, "RasterState must not have implicit padding.");
8896

89-
VulkanPipelineCache(VkDevice device, VulkanContext const& context);
97+
VulkanPipelineCache(DriverBase& driver, VkDevice device, VulkanContext const& context);
9098

91-
void bindLayout(VkPipelineLayout layout) noexcept;
99+
// Loads a fake pipeline into memory on a separate thread, with the intent of
100+
// preloading the Vulkan cache with enough information to have a cache hit when
101+
// compiling the pipeline on the main thread at draw time. This is very dependent
102+
// on the implementation of the driver on the current device; it's expected to work
103+
// on devices with VK_EXT_vertex_input_dynamic_state and VK_KHR_dynamic_rendering.
104+
void asyncPreloadCache(fvkmemory::resource_ptr<VulkanProgram> program,
105+
VkPipelineLayout layout);
92106

93107
// Creates a new pipeline if necessary and binds it using vkCmdBindPipeline.
94108
void bindPipeline(VulkanCommandBuffer* commands);
95109

96110
// Each of the following methods are fast and do not make Vulkan calls.
111+
void bindLayout(VkPipelineLayout layout) noexcept;
97112
void bindProgram(fvkmemory::resource_ptr<VulkanProgram> program) noexcept;
98113
void bindRasterState(RasterState const& rasterState) noexcept;
99114
void bindRenderPass(VkRenderPass renderPass, int subpassIndex) noexcept;
@@ -211,6 +226,14 @@ class VulkanPipelineCache {
211226
// Current bindings for the pipeline and descriptor sets.
212227
PipelineKey mBoundPipeline = {};
213228

229+
// Thread pool that allows us to "prewarm" the pipeline cache, reducing draw-time
230+
// pipeline compilation time.
231+
CompilerThreadPool mCompilerThreadPool;
232+
233+
// Callback manager that allows us to notify the frontend when a set of pipelines have
234+
// been prewarmed, signifying that it is safe to compile pipelines at draw time.
235+
CallbackManager mCallbackManager;
236+
214237
[[maybe_unused]] VulkanContext const& mContext;
215238
};
216239

0 commit comments

Comments
 (0)