Blender V4.5
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 /* Render pass rendering */
148 VkRenderPass vk_render_pass;
149
150 bool operator==(const FragmentOut &other) const
151 {
152#if 1
153 return hash() == other.hash();
154#else
159 {
160 return false;
161 }
162
163 if (memcmp(color_attachment_formats.data(),
165 color_attachment_formats.size() * sizeof(VkFormat)) == 0)
166 {
167 return false;
168 }
169 return true;
170#endif
171 }
172
174 {
178 hash = hash * 33 ^ XXH3_64bits(color_attachment_formats.data(),
179 color_attachment_formats.size() * sizeof(VkFormat));
180 return hash;
181 }
182 };
183
188
191 VkPipelineLayout vk_pipeline_layout;
193
194 bool operator==(const VKGraphicsInfo &other) const
195 {
196 return vertex_in == other.vertex_in && pre_rasterization == other.pre_rasterization &&
201 };
203 {
204 uint64_t hash = 0;
205 hash = hash * 33 ^ vertex_in.hash();
206 hash = hash * 33 ^ pre_rasterization.hash();
207 hash = hash * 33 ^ fragment_shader.hash();
208 hash = hash * 33 ^ fragment_out.hash();
210 hash = hash * 33 ^ specialization_constants.hash();
211 hash = hash * 33 ^ state.data;
212 hash = hash * 33 ^ mutable_state.data[0];
213 hash = hash * 33 ^ mutable_state.data[1];
214 hash = hash * 33 ^ mutable_state.data[2];
215 return hash;
216 }
217};
218
252 friend class VKDevice;
253
254 public:
255 private:
256 Map<VKComputeInfo, VkPipeline> compute_pipelines_;
257 Map<VKGraphicsInfo, VkPipeline> graphic_pipelines_;
258 /* Partially initialized structures to reuse. */
259 VkComputePipelineCreateInfo vk_compute_pipeline_create_info_;
260
261 VkGraphicsPipelineCreateInfo vk_graphics_pipeline_create_info_;
262 VkPipelineRenderingCreateInfo vk_pipeline_rendering_create_info_;
263 VkPipelineShaderStageCreateInfo vk_pipeline_shader_stage_create_info_[3];
264 VkPipelineInputAssemblyStateCreateInfo vk_pipeline_input_assembly_state_create_info_;
265 VkPipelineVertexInputStateCreateInfo vk_pipeline_vertex_input_state_create_info_;
266
267 VkPipelineRasterizationStateCreateInfo vk_pipeline_rasterization_state_create_info_;
268 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT
269 vk_pipeline_rasterization_provoking_vertex_state_info_;
270
271 Vector<VkDynamicState> vk_dynamic_states_;
272 VkPipelineDynamicStateCreateInfo vk_pipeline_dynamic_state_create_info_;
273
274 VkPipelineViewportStateCreateInfo vk_pipeline_viewport_state_create_info_;
275 VkPipelineDepthStencilStateCreateInfo vk_pipeline_depth_stencil_state_create_info_;
276
277 VkPipelineMultisampleStateCreateInfo vk_pipeline_multisample_state_create_info_;
278
279 Vector<VkPipelineColorBlendAttachmentState> vk_pipeline_color_blend_attachment_states_;
280 VkPipelineColorBlendStateCreateInfo vk_pipeline_color_blend_state_create_info_;
281 VkPipelineColorBlendAttachmentState vk_pipeline_color_blend_attachment_state_template_;
282
283 VkSpecializationInfo vk_specialization_info_;
284 Vector<VkSpecializationMapEntry> vk_specialization_map_entries_;
285 VkPushConstantRange vk_push_constant_range_;
286
287 VkPipelineCache vk_pipeline_cache_static_;
288 VkPipelineCache vk_pipeline_cache_non_static_;
289
290 Mutex mutex_;
291
292 public:
294
295 void init();
296
303 VkPipeline get_or_create_compute_pipeline(VKComputeInfo &compute_info,
304 bool is_static_shader,
305 VkPipeline vk_pipeline_base);
306
313 VkPipeline get_or_create_graphics_pipeline(VKGraphicsInfo &graphics_info,
314 bool is_static_shader,
315 VkPipeline vk_pipeline_base);
316
320 void discard(VKDiscardPool &discard_pool, VkPipelineLayout vk_pipeline_layout);
321
328 void free_data();
329
344 void read_from_disk();
345
360 void write_to_disk();
361
362 private:
363 VkSpecializationInfo *specialization_info_update(
364 Span<shader::SpecializationConstant::Value> specialization_constants);
365 void specialization_info_reset();
366};
367
368} // 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