Blender V5.0
vk_pipeline_pool.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include "xxhash.h"
12
13#include "BLI_map.hh"
14#include "BLI_mutex.hh"
15#include "BLI_utility_mixins.hh"
16
17#include "gpu_state_private.hh"
18
19#include "vk_common.hh"
20
21namespace blender::gpu {
22class VKDevice;
23class VKDiscardPool;
24
48
57 struct VertexIn {
58 VkPrimitiveTopology vk_topology;
61
62 bool operator==(const VertexIn &other) const
63 {
64 /* TODO: use an exact implementation and remove the hash compare. */
65#if 0
66 return vk_topology == other.vk_topology && attributes.hash() == other.attributes.hash() &&
67 bindings.hash() == other.bindings.hash();
68#endif
69 return hash() == other.hash();
70 }
71
72 uint64_t hash() const
73 {
75 hash = hash * 33 ^
76 XXH3_64bits(attributes.data(),
77 attributes.size() * sizeof(VkVertexInputAttributeDescription));
78 hash = hash * 33 ^ XXH3_64bits(bindings.data(),
79 bindings.size() * sizeof(VkVertexInputBindingDescription));
80 return hash;
81 }
82 };
84 VkShaderModule vk_vertex_module;
85 VkShaderModule vk_geometry_module;
86 bool operator==(const PreRasterization &other) const
87 {
88 return vk_vertex_module == other.vk_vertex_module &&
90 }
91 uint64_t hash() const
92 {
93 uint64_t hash = 0;
96 return hash;
97 }
98 };
100 VkShaderModule vk_fragment_module;
103 std::optional<uint64_t> cached_hash;
104
105 bool operator==(const FragmentShader &other) const
106 {
108 viewports.size() != other.viewports.size() || scissors.size() != other.scissors.size() ||
109 hash() != other.hash())
110 {
111 return false;
112 }
113
114 return true;
115 }
116
118 {
119 if (cached_hash.has_value()) {
120 return *cached_hash;
121 }
122 return calc_hash();
123 }
124
126 {
127 cached_hash = calc_hash();
128 }
129
130 private:
131 uint64_t calc_hash() const
132 {
134 hash = hash * 33 ^ uint64_t(viewports.size());
135 hash = hash * 33 ^ uint64_t(scissors.size());
136
137 return hash;
138 }
139 };
140 struct FragmentOut {
142
143 /* Dynamic rendering */
147
148 bool operator==(const FragmentOut &other) const
149 {
150#if 1
151 return hash() == other.hash();
152#else
156 {
157 return false;
158 }
159
160 if (memcmp(color_attachment_formats.data(),
162 color_attachment_formats.size() * sizeof(VkFormat)) == 0)
163 {
164 return false;
165 }
166 return true;
167#endif
168 }
169
171 {
174 hash = hash * 33 ^ XXH3_64bits(color_attachment_formats.data(),
175 color_attachment_formats.size() * sizeof(VkFormat));
176 return hash;
177 }
178 };
179
184
187 VkPipelineLayout vk_pipeline_layout;
189
190 bool operator==(const VKGraphicsInfo &other) const
191 {
192 return vertex_in == other.vertex_in && pre_rasterization == other.pre_rasterization &&
197 };
199 {
200 uint64_t hash = 0;
201 hash = hash * 33 ^ vertex_in.hash();
202 hash = hash * 33 ^ pre_rasterization.hash();
203 hash = hash * 33 ^ fragment_shader.hash();
204 hash = hash * 33 ^ fragment_out.hash();
206 hash = hash * 33 ^ specialization_constants.hash();
207 hash = hash * 33 ^ state.data;
208 hash = hash * 33 ^ mutable_state.data[0];
209 hash = hash * 33 ^ mutable_state.data[1];
210 hash = hash * 33 ^ mutable_state.data[2];
211 return hash;
212 }
213};
214
248 friend class VKDevice;
249
250 public:
251 private:
252 Map<VKComputeInfo, VkPipeline> compute_pipelines_;
253 Map<VKGraphicsInfo, VkPipeline> graphic_pipelines_;
254 /* Partially initialized structures to reuse. */
255 VkComputePipelineCreateInfo vk_compute_pipeline_create_info_;
256
257 VkGraphicsPipelineCreateInfo vk_graphics_pipeline_create_info_;
258 VkPipelineRenderingCreateInfo vk_pipeline_rendering_create_info_;
259 VkPipelineShaderStageCreateInfo vk_pipeline_shader_stage_create_info_[3];
260 VkPipelineInputAssemblyStateCreateInfo vk_pipeline_input_assembly_state_create_info_;
261 VkPipelineVertexInputStateCreateInfo vk_pipeline_vertex_input_state_create_info_;
262
263 VkPipelineRasterizationStateCreateInfo vk_pipeline_rasterization_state_create_info_;
264 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT
265 vk_pipeline_rasterization_provoking_vertex_state_info_;
266
267 Vector<VkDynamicState> vk_dynamic_states_;
268 VkPipelineDynamicStateCreateInfo vk_pipeline_dynamic_state_create_info_;
269
270 VkPipelineViewportStateCreateInfo vk_pipeline_viewport_state_create_info_;
271 VkPipelineDepthStencilStateCreateInfo vk_pipeline_depth_stencil_state_create_info_;
272
273 VkPipelineMultisampleStateCreateInfo vk_pipeline_multisample_state_create_info_;
274
275 Vector<VkPipelineColorBlendAttachmentState> vk_pipeline_color_blend_attachment_states_;
276 VkPipelineColorBlendStateCreateInfo vk_pipeline_color_blend_state_create_info_;
277 VkPipelineColorBlendAttachmentState vk_pipeline_color_blend_attachment_state_template_;
278
279 VkSpecializationInfo vk_specialization_info_;
280 Vector<VkSpecializationMapEntry> vk_specialization_map_entries_;
281 VkPushConstantRange vk_push_constant_range_;
282
283 VkPipelineCache vk_pipeline_cache_static_;
284 VkPipelineCache vk_pipeline_cache_non_static_;
285
286 Mutex mutex_;
287
288 public:
290
291 void init();
292
299 VkPipeline get_or_create_compute_pipeline(VKComputeInfo &compute_info,
300 bool is_static_shader,
301 VkPipeline vk_pipeline_base);
302
309 VkPipeline get_or_create_graphics_pipeline(VKGraphicsInfo &graphics_info,
310 bool is_static_shader,
311 VkPipeline vk_pipeline_base);
312
316 void discard(VKDiscardPool &discard_pool, VkPipelineLayout vk_pipeline_layout);
317
324 void free_data();
325
340 void read_from_disk();
341
356 void write_to_disk();
357
358 private:
359 VkSpecializationInfo *specialization_info_update(
360 Span<shader::SpecializationConstant::Value> specialization_constants);
361 void specialization_info_reset();
362};
363
364} // namespace blender::gpu
unsigned long long int uint64_t
int64_t size() const
uint64_t hash() const
T * data()
NonCopyable(const NonCopyable &other)=delete
VkPipeline get_or_create_compute_pipeline(VKComputeInfo &compute_info, bool is_static_shader, VkPipeline vk_pipeline_base)
VkPipeline get_or_create_graphics_pipeline(VKGraphicsInfo &graphics_info, bool is_static_shader, VkPipeline vk_pipeline_base)
void discard(VKDiscardPool &discard_pool, VkPipelineLayout vk_pipeline_layout)
std::mutex Mutex
Definition BLI_mutex.hh:47
Vector< shader::SpecializationConstant::Value > specialization_constants
VkPipelineLayout vk_pipeline_layout
bool operator==(const VKComputeInfo &other) const
bool operator==(const FragmentOut &other) const
bool operator==(const FragmentShader &other) const
bool operator==(const PreRasterization &other) const
Vector< VkVertexInputBindingDescription > bindings
Vector< VkVertexInputAttributeDescription > attributes
bool operator==(const VertexIn &other) const
bool operator==(const VKGraphicsInfo &other) const
Vector< shader::SpecializationConstant::Value > specialization_constants