Blender V4.3
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
9#pragma once
10
11#include <mutex>
12
13#include "BLI_map.hh"
14#include "BLI_utility_mixins.hh"
15
16#include "gpu_state_private.hh"
17
18#include "vk_common.hh"
19
20namespace blender {
21namespace gpu {
22
27 VkShaderModule vk_shader_module;
28 VkPipelineLayout vk_pipeline_layout;
30
31 bool operator==(const VKComputeInfo &other) const
32 {
33 return vk_shader_module == other.vk_shader_module &&
34 vk_pipeline_layout == other.vk_pipeline_layout &&
35 specialization_constants == other.specialization_constants;
36 };
37};
38
47 struct VertexIn {
48 VkPrimitiveTopology vk_topology;
51
52 bool operator==(const VertexIn &other) const
53 {
54 /* TODO: use an exact implementation and remove the hash compare. */
55#if 0
56 return vk_topology == other.vk_topology && attributes.hash() == other.attributes.hash() &&
57 bindings.hash() == other.bindings.hash();
58#endif
59 return hash() == other.hash();
60 }
61
62 uint64_t hash() const
63 {
64 uint64_t hash = 0;
65 hash = hash * 33 ^ uint64_t(vk_topology);
66 for (const VkVertexInputAttributeDescription &attribute : attributes) {
67 hash = hash * 33 ^ uint64_t(attribute.location);
68 hash = hash * 33 ^ uint64_t(attribute.binding);
69 hash = hash * 33 ^ uint64_t(attribute.format);
70 hash = hash * 33 ^ uint64_t(attribute.offset);
71 }
72 for (const VkVertexInputBindingDescription &binding : bindings) {
73 hash = hash * 33 ^ uint64_t(binding.binding);
74 hash = hash * 33 ^ uint64_t(binding.inputRate);
75 hash = hash * 33 ^ uint64_t(binding.stride);
76 }
77 return hash;
78 }
79 };
81 VkShaderModule vk_vertex_module;
82 VkShaderModule vk_geometry_module;
83 bool operator==(const PreRasterization &other) const
84 {
85 return vk_vertex_module == other.vk_vertex_module &&
86 vk_geometry_module == other.vk_geometry_module;
87 }
88 uint64_t hash() const
89 {
90 uint64_t hash = 0;
93 return hash;
94 }
95 };
97 VkShaderModule vk_fragment_module;
100 std::optional<uint64_t> cached_hash;
101
102 bool operator==(const FragmentShader &other) const
103 {
104 /* TODO: Do not use hash. */
105 return vk_fragment_module == other.vk_fragment_module && hash() == other.hash();
106 }
107
109 {
110 if (cached_hash.has_value()) {
111 return *cached_hash;
112 }
113 return calc_hash();
114 }
115
117 {
118 cached_hash = calc_hash();
119 }
120
121 private:
122 uint64_t calc_hash() const
123 {
124 uint64_t hash = 0;
126 for (const VkViewport &vk_viewport : viewports) {
127 hash = hash * 33 ^ uint64_t(vk_viewport.x);
128 hash = hash * 33 ^ uint64_t(vk_viewport.y);
129 hash = hash * 33 ^ uint64_t(vk_viewport.width);
130 hash = hash * 33 ^ uint64_t(vk_viewport.height);
131 hash = hash * 33 ^ uint64_t(vk_viewport.minDepth);
132 hash = hash * 33 ^ uint64_t(vk_viewport.maxDepth);
133 }
134 for (const VkRect2D &scissor : scissors) {
135 hash = hash * 33 ^ uint64_t(scissor.offset.x);
136 hash = hash * 33 ^ uint64_t(scissor.offset.y);
137 hash = hash * 33 ^ uint64_t(scissor.extent.width);
138 hash = hash * 33 ^ uint64_t(scissor.extent.height);
139 }
140 return hash;
141 }
142 };
143 struct FragmentOut {
147
148 bool operator==(const FragmentOut &other) const
149 {
150 return hash() == other.hash();
151 }
152
154 {
155 uint64_t hash = 0;
158 for (VkFormat color_attachment_format : color_attachment_formats) {
159 hash = hash * 33 ^ uint64_t(color_attachment_format);
160 }
161
162 return hash;
163 }
164 };
165
170
173 VkPipelineLayout vk_pipeline_layout;
175
176 bool operator==(const VKGraphicsInfo &other) const
177 {
178 return vertex_in == other.vertex_in && pre_rasterization == other.pre_rasterization &&
179 fragment_shader == other.fragment_shader && fragment_out == other.fragment_out &&
180 vk_pipeline_layout == other.vk_pipeline_layout &&
181 specialization_constants == other.specialization_constants && state == other.state &&
182 mutable_state == other.mutable_state;
183 };
185 {
186 uint64_t hash = 0;
187 hash = hash * 33 ^ vertex_in.hash();
188 hash = hash * 33 ^ pre_rasterization.hash();
189 hash = hash * 33 ^ fragment_shader.hash();
190 hash = hash * 33 ^ fragment_out.hash();
193 hash = hash * 33 ^ state.data;
194 hash = hash * 33 ^ mutable_state.data[0];
195 hash = hash * 33 ^ mutable_state.data[1];
196 hash = hash * 33 ^ mutable_state.data[2];
197 return hash;
198 }
199};
200
201} // namespace gpu
202
203template<> struct DefaultHash<gpu::VKComputeInfo> {
205 {
207 hash = hash * 33 ^ uint64_t(key.vk_pipeline_layout);
209 return hash;
210 }
211};
212
213namespace gpu {
214class VKDevice;
215
249 friend class VKDevice;
250
251 public:
252 private:
253 Map<VKComputeInfo, VkPipeline> compute_pipelines_;
254 Map<VKGraphicsInfo, VkPipeline> graphic_pipelines_;
255 /* Partially initialized structures to reuse. */
256 VkComputePipelineCreateInfo vk_compute_pipeline_create_info_;
257
258 VkGraphicsPipelineCreateInfo vk_graphics_pipeline_create_info_;
259 VkPipelineRenderingCreateInfo vk_pipeline_rendering_create_info_;
260 VkPipelineShaderStageCreateInfo vk_pipeline_shader_stage_create_info_[3];
261 VkPipelineInputAssemblyStateCreateInfo vk_pipeline_input_assembly_state_create_info_;
262 VkPipelineVertexInputStateCreateInfo vk_pipeline_vertex_input_state_create_info_;
263
264 VkPipelineRasterizationStateCreateInfo vk_pipeline_rasterization_state_create_info_;
265 VkPipelineViewportStateCreateInfo vk_pipeline_viewport_state_create_info_;
266 VkPipelineDepthStencilStateCreateInfo vk_pipeline_depth_stencil_state_create_info_;
267
268 VkPipelineMultisampleStateCreateInfo vk_pipeline_multisample_state_create_info_;
269
270 Vector<VkPipelineColorBlendAttachmentState> vk_pipeline_color_blend_attachment_states_;
271 VkPipelineColorBlendStateCreateInfo vk_pipeline_color_blend_state_create_info_;
272 VkPipelineColorBlendAttachmentState vk_pipeline_color_blend_attachment_state_template_;
273
274 VkSpecializationInfo vk_specialization_info_;
275 Vector<VkSpecializationMapEntry> vk_specialization_map_entries_;
276 VkPushConstantRange vk_push_constant_range_;
277
278 VkPipelineCache vk_pipeline_cache_static_;
279 VkPipelineCache vk_pipeline_cache_non_static_;
280
281 std::mutex mutex_;
282
283 public:
285
286 void init();
287
294 VkPipeline get_or_create_compute_pipeline(VKComputeInfo &compute_info,
295 bool is_static_shader,
296 VkPipeline vk_pipeline_base);
297
304 VkPipeline get_or_create_graphics_pipeline(VKGraphicsInfo &graphics_info,
305 bool is_static_shader,
306 VkPipeline vk_pipeline_base);
307
311 void remove(Span<VkShaderModule> vk_shader_modules);
312
319 void free_data();
320
335 void read_from_disk();
336
351 void write_to_disk();
352
353 private:
354 VkSpecializationInfo *specialization_info_update(
355 Span<shader::SpecializationConstant::Value> specialization_constants);
356 void specialization_info_reset();
357};
358
359} // namespace gpu
360
361} // namespace blender
uint64_t hash() const
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 remove(Span< VkShaderModule > vk_shader_modules)
uint64_t get_default_hash(const T &v)
Definition BLI_hash.hh:219
#define hash
Definition noise.c:154
unsigned __int64 uint64_t
Definition stdint.h:90
uint64_t operator()(const gpu::VKComputeInfo &key) const
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