Vulkan: Separate pipeline caches for (non)static shaders

This change does some preparations before we implement persistent
caching for static shaders.

- Move ownership of pipeline cache to the pipeline pool.
- Use two pools. one is only used for static shaders
  other for non static shaders.

Related to #126229

Pull Request: https://projects.blender.org/blender/blender/pulls/127100
This commit is contained in:
Jeroen Bakker
2024-09-03 15:25:50 +02:00
parent a8c08e4a8c
commit b2a0d29345
6 changed files with 39 additions and 26 deletions

View File

@@ -35,7 +35,6 @@ void VKDevice::reinit()
void VKDevice::deinit()
{
VK_ALLOCATION_CALLBACKS
if (!is_initialized()) {
return;
}
@@ -52,7 +51,6 @@ void VKDevice::deinit()
thread_data_.clear();
}
pipelines.free_data();
vkDestroyPipelineCache(vk_device_, vk_pipeline_cache_, vk_allocation_callbacks);
descriptor_set_layouts_.deinit();
vmaDestroyAllocator(mem_allocator_);
mem_allocator_ = VK_NULL_HANDLE;
@@ -92,7 +90,7 @@ void VKDevice::init(void *ghost_context)
init_functions();
init_debug_callbacks();
init_memory_allocator();
init_pipeline_cache();
pipelines.init();
samplers_.init();
init_dummy_buffer();
@@ -184,14 +182,6 @@ void VKDevice::init_memory_allocator()
vmaCreateAllocator(&info, &mem_allocator_);
}
void VKDevice::init_pipeline_cache()
{
VK_ALLOCATION_CALLBACKS;
VkPipelineCacheCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
vkCreatePipelineCache(vk_device_, &create_info, vk_allocation_callbacks, &vk_pipeline_cache_);
}
void VKDevice::init_dummy_buffer()
{
dummy_buffer.create(sizeof(float4x4),

View File

@@ -136,7 +136,6 @@ class VKDevice : public NonCopyable {
/** Allocator used for texture and buffers and other resources. */
VmaAllocator mem_allocator_ = VK_NULL_HANDLE;
VkPipelineCache vk_pipeline_cache_ = VK_NULL_HANDLE;
/** Limits of the device linked to this context. */
VkPhysicalDeviceProperties vk_physical_device_properties_ = {};
@@ -229,11 +228,6 @@ class VKDevice : public NonCopyable {
return mem_allocator_;
}
VkPipelineCache vk_pipeline_cache_get() const
{
return vk_pipeline_cache_;
}
VKDescriptorSetLayouts &descriptor_set_layouts_get()
{
return descriptor_set_layouts_;
@@ -319,7 +313,6 @@ class VKDevice : public NonCopyable {
void init_physical_device_extensions();
void init_debug_callbacks();
void init_memory_allocator();
void init_pipeline_cache();
/**
* Initialize the functions struct with extension specific function pointer.
*/

View File

@@ -115,6 +115,17 @@ VKPipelinePool::VKPipelinePool()
vk_push_constant_range_.offset = 0;
vk_push_constant_range_.size = 0;
}
void VKPipelinePool::init()
{
VK_ALLOCATION_CALLBACKS;
VKDevice &device = VKBackend::get().device;
VkPipelineCacheCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
vkCreatePipelineCache(
device.vk_handle(), &create_info, vk_allocation_callbacks, &vk_pipeline_cache_static_);
vkCreatePipelineCache(
device.vk_handle(), &create_info, vk_allocation_callbacks, &vk_pipeline_cache_non_static_);
}
VkSpecializationInfo *VKPipelinePool::specialization_info_update(
Span<shader::SpecializationConstant::Value> specialization_constants)
@@ -147,6 +158,7 @@ void VKPipelinePool::specialization_info_reset()
}
VkPipeline VKPipelinePool::get_or_create_compute_pipeline(VKComputeInfo &compute_info,
const bool is_static_shader,
VkPipeline vk_pipeline_base)
{
std::scoped_lock lock(mutex_);
@@ -170,7 +182,8 @@ VkPipeline VKPipelinePool::get_or_create_compute_pipeline(VKComputeInfo &compute
VkPipeline pipeline = VK_NULL_HANDLE;
vkCreateComputePipelines(device.vk_handle(),
device.vk_pipeline_cache_get(),
is_static_shader ? vk_pipeline_cache_static_ :
vk_pipeline_cache_non_static_,
1,
&vk_compute_pipeline_create_info_,
vk_allocation_callbacks,
@@ -188,6 +201,7 @@ VkPipeline VKPipelinePool::get_or_create_compute_pipeline(VKComputeInfo &compute
}
VkPipeline VKPipelinePool::get_or_create_graphics_pipeline(VKGraphicsInfo &graphics_info,
const bool is_static_shader,
VkPipeline vk_pipeline_base)
{
std::scoped_lock lock(mutex_);
@@ -525,7 +539,8 @@ VkPipeline VKPipelinePool::get_or_create_graphics_pipeline(VKGraphicsInfo &graph
VkPipeline pipeline = VK_NULL_HANDLE;
vkCreateGraphicsPipelines(device.vk_handle(),
device.vk_pipeline_cache_get(),
is_static_shader ? vk_pipeline_cache_static_ :
vk_pipeline_cache_non_static_,
1,
&vk_graphics_pipeline_create_info_,
vk_allocation_callbacks,
@@ -619,6 +634,10 @@ void VKPipelinePool::free_data()
vkDestroyPipeline(device.vk_handle(), vk_pipeline, vk_allocation_callbacks);
}
compute_pipelines_.clear();
vkDestroyPipelineCache(device.vk_handle(), vk_pipeline_cache_static_, vk_allocation_callbacks);
vkDestroyPipelineCache(
device.vk_handle(), vk_pipeline_cache_non_static_, vk_allocation_callbacks);
}
} // namespace blender::gpu

View File

@@ -275,10 +275,16 @@ class VKPipelinePool : public NonCopyable {
Vector<VkSpecializationMapEntry> vk_specialization_map_entries_;
VkPushConstantRange vk_push_constant_range_;
VkPipelineCache vk_pipeline_cache_static_;
VkPipelineCache vk_pipeline_cache_non_static_;
std::mutex mutex_;
public:
VKPipelinePool();
void init();
/**
* Get an existing or create a new compute pipeline based on the provided ComputeInfo.
*
@@ -286,7 +292,8 @@ class VKPipelinePool : public NonCopyable {
* pipeline creation process.
*/
VkPipeline get_or_create_compute_pipeline(VKComputeInfo &compute_info,
VkPipeline vk_pipeline_base = VK_NULL_HANDLE);
bool is_static_shader,
VkPipeline vk_pipeline_base);
/**
* Get an existing or create a new compute pipeline based on the provided ComputeInfo.
@@ -295,7 +302,8 @@ class VKPipelinePool : public NonCopyable {
* pipeline creation process.
*/
VkPipeline get_or_create_graphics_pipeline(VKGraphicsInfo &graphics_info,
VkPipeline vk_pipeline_base = VK_NULL_HANDLE);
bool is_static_shader,
VkPipeline vk_pipeline_base);
/**
* Remove all shader pipelines that uses the given shader_module.

View File

@@ -576,6 +576,7 @@ void VKShader::init(const shader::ShaderCreateInfo &info, bool /*is_batch_compil
VKShaderInterface *vk_interface = new VKShaderInterface();
vk_interface->init(info);
interface = vk_interface;
is_static_shader_ = info.do_static_compilation_;
}
VKShader::~VKShader()
@@ -1287,8 +1288,8 @@ VkPipeline VKShader::ensure_and_get_compute_pipeline()
VKDevice &device = VKBackend::get().device;
/* Store result in local variable to ensure thread safety. */
VkPipeline vk_pipeline = device.pipelines.get_or_create_compute_pipeline(compute_info,
vk_pipeline_);
VkPipeline vk_pipeline = device.pipelines.get_or_create_compute_pipeline(
compute_info, is_static_shader_, vk_pipeline_);
vk_pipeline_ = vk_pipeline;
return vk_pipeline;
}
@@ -1333,8 +1334,8 @@ VkPipeline VKShader::ensure_and_get_graphics_pipeline(GPUPrimType primitive,
VKDevice &device = VKBackend::get().device;
/* Store result in local variable to ensure thread safety. */
VkPipeline vk_pipeline = device.pipelines.get_or_create_graphics_pipeline(graphics_info,
vk_pipeline_);
VkPipeline vk_pipeline = device.pipelines.get_or_create_graphics_pipeline(
graphics_info, is_static_shader_, vk_pipeline_);
vk_pipeline_ = vk_pipeline;
return vk_pipeline;
}

View File

@@ -44,6 +44,8 @@ class VKShader : public Shader {
* What is the reason to store the last pipeline. */
VkPipeline vk_pipeline_ = VK_NULL_HANDLE;
bool is_static_shader_ = false;
public:
VkPipelineLayout vk_pipeline_layout = VK_NULL_HANDLE;
VKPushConstants push_constants;