Blender V5.0
vk_pipeline_pool.cc
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#include "BKE_appdir.hh"
10
11#include "BLI_fileops.hh"
12#include "BLI_path_utils.hh"
13
14#include "CLG_log.h"
15
16#include "vk_backend.hh"
17#include "vk_pipeline_pool.hh"
18
19#ifdef WITH_BUILDINFO
20extern "C" char build_hash[];
21static CLG_LogRef LOG = {"gpu.vulkan"};
22#endif
23
24namespace blender::gpu {
25
27{
28 /* Initialize VkComputePipelineCreateInfo */
29 vk_compute_pipeline_create_info_.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
30 vk_compute_pipeline_create_info_.pNext = nullptr;
31 vk_compute_pipeline_create_info_.flags = 0;
32 vk_compute_pipeline_create_info_.layout = VK_NULL_HANDLE;
33 vk_compute_pipeline_create_info_.basePipelineHandle = VK_NULL_HANDLE;
34 vk_compute_pipeline_create_info_.basePipelineIndex = 0;
35 VkPipelineShaderStageCreateInfo &vk_pipeline_shader_stage_create_info =
36 vk_compute_pipeline_create_info_.stage;
37 vk_pipeline_shader_stage_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
38 vk_pipeline_shader_stage_create_info.pNext = nullptr;
39 vk_pipeline_shader_stage_create_info.flags = 0;
40 vk_pipeline_shader_stage_create_info.stage = VK_SHADER_STAGE_COMPUTE_BIT;
41 vk_pipeline_shader_stage_create_info.module = VK_NULL_HANDLE;
42 vk_pipeline_shader_stage_create_info.pName = "main";
43
44 /* Initialize VkGraphicsPipelineCreateInfo */
45 vk_graphics_pipeline_create_info_ = {};
46 vk_graphics_pipeline_create_info_.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
47 vk_graphics_pipeline_create_info_.pNext = &vk_pipeline_rendering_create_info_;
48 vk_graphics_pipeline_create_info_.stageCount = 0;
49 vk_graphics_pipeline_create_info_.pStages = vk_pipeline_shader_stage_create_info_;
50 vk_graphics_pipeline_create_info_.pInputAssemblyState =
51 &vk_pipeline_input_assembly_state_create_info_;
52 vk_graphics_pipeline_create_info_.pVertexInputState =
53 &vk_pipeline_vertex_input_state_create_info_;
54 vk_graphics_pipeline_create_info_.pRasterizationState =
55 &vk_pipeline_rasterization_state_create_info_;
56 vk_graphics_pipeline_create_info_.pDynamicState = &vk_pipeline_dynamic_state_create_info_;
57 vk_graphics_pipeline_create_info_.pViewportState = &vk_pipeline_viewport_state_create_info_;
58 vk_graphics_pipeline_create_info_.pMultisampleState =
59 &vk_pipeline_multisample_state_create_info_;
60 vk_graphics_pipeline_create_info_.pColorBlendState = &vk_pipeline_color_blend_state_create_info_;
61
62 /* Initialize VkPipelineRenderingCreateInfo */
63 vk_pipeline_rendering_create_info_ = {};
64 vk_pipeline_rendering_create_info_.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
65
66 /* Initialize VkPipelineShaderStageCreateInfo */
67 for (int i : IndexRange(3)) {
68 vk_pipeline_shader_stage_create_info_[i].sType =
69 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
70 vk_pipeline_shader_stage_create_info_[i].pNext = nullptr;
71 vk_pipeline_shader_stage_create_info_[i].flags = 0;
72 vk_pipeline_shader_stage_create_info_[i].module = VK_NULL_HANDLE;
73 vk_pipeline_shader_stage_create_info_[i].pName = "main";
74 }
75 vk_pipeline_shader_stage_create_info_[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
76 vk_pipeline_shader_stage_create_info_[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
77 vk_pipeline_shader_stage_create_info_[2].stage = VK_SHADER_STAGE_GEOMETRY_BIT;
78
79 /* Initialize VkPipelineInputAssemblyStateCreateInfo */
80 vk_pipeline_input_assembly_state_create_info_ = {};
81 vk_pipeline_input_assembly_state_create_info_.sType =
82 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
83
84 /* Initialize VkPipelineVertexInputStateCreateInfo */
85 vk_pipeline_vertex_input_state_create_info_ = {};
86 vk_pipeline_vertex_input_state_create_info_.sType =
87 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
88
89 /* Initialize VkPipelineRasterizationStateCreateInfo */
90 vk_pipeline_rasterization_state_create_info_ = {};
91 vk_pipeline_rasterization_state_create_info_.sType =
92 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
93 vk_pipeline_rasterization_state_create_info_.lineWidth = 1.0f;
94 vk_pipeline_rasterization_state_create_info_.frontFace = VK_FRONT_FACE_CLOCKWISE;
95 vk_pipeline_rasterization_state_create_info_.pNext =
96 &vk_pipeline_rasterization_provoking_vertex_state_info_;
97
98 vk_pipeline_rasterization_provoking_vertex_state_info_ = {};
99 vk_pipeline_rasterization_provoking_vertex_state_info_.sType =
100 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
101 vk_pipeline_rasterization_provoking_vertex_state_info_.provokingVertexMode =
102 VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
103
104 vk_dynamic_states_ = {
105 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH};
106 vk_pipeline_dynamic_state_create_info_ = {};
107 vk_pipeline_dynamic_state_create_info_.sType =
108 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
109
110 vk_pipeline_viewport_state_create_info_ = {};
111 vk_pipeline_viewport_state_create_info_.sType =
112 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
113
114 /* Initialize VkPipelineMultisampleStateCreateInfo */
115 vk_pipeline_multisample_state_create_info_ = {};
116 vk_pipeline_multisample_state_create_info_.sType =
117 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
118 vk_pipeline_multisample_state_create_info_.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
119 vk_pipeline_multisample_state_create_info_.minSampleShading = 1.0f;
120
121 /* Initialize VkPipelineColorBlendStateCreateInfo */
122 vk_pipeline_color_blend_state_create_info_ = {};
123 vk_pipeline_color_blend_state_create_info_.sType =
124 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
125 vk_pipeline_color_blend_attachment_state_template_.colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
126 VK_COLOR_COMPONENT_G_BIT |
127 VK_COLOR_COMPONENT_B_BIT |
128 VK_COLOR_COMPONENT_A_BIT;
129 /* Initialize VkPipelineDepthStencilStateCreateInfo */
130 vk_pipeline_depth_stencil_state_create_info_ = {};
131 vk_pipeline_depth_stencil_state_create_info_.sType =
132 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
133
134 /* Initialize VkSpecializationInfo. */
135 vk_specialization_info_.mapEntryCount = 0;
136 vk_specialization_info_.pMapEntries = nullptr;
137 vk_specialization_info_.dataSize = 0;
138 vk_specialization_info_.pData = nullptr;
139
140 vk_push_constant_range_.stageFlags = 0;
141 vk_push_constant_range_.offset = 0;
142 vk_push_constant_range_.size = 0;
143}
145{
146 VKDevice &device = VKBackend::get().device;
147 VkPipelineCacheCreateInfo create_info = {};
148 create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
149 vkCreatePipelineCache(device.vk_handle(), &create_info, nullptr, &vk_pipeline_cache_static_);
150 debug::object_label(vk_pipeline_cache_static_, "VkPipelineCache.Static");
151 vkCreatePipelineCache(device.vk_handle(), &create_info, nullptr, &vk_pipeline_cache_non_static_);
152 debug::object_label(vk_pipeline_cache_non_static_, "VkPipelineCache.Dynamic");
153}
154
155VkSpecializationInfo *VKPipelinePool::specialization_info_update(
156 Span<shader::SpecializationConstant::Value> specialization_constants)
157{
158 if (specialization_constants.is_empty()) {
159 return nullptr;
160 }
161
162 while (vk_specialization_map_entries_.size() < specialization_constants.size()) {
163 uint32_t constant_id = vk_specialization_map_entries_.size();
164 VkSpecializationMapEntry vk_specialization_map_entry = {};
165 vk_specialization_map_entry.constantID = constant_id;
166 vk_specialization_map_entry.offset = constant_id * sizeof(uint32_t);
167 vk_specialization_map_entry.size = sizeof(uint32_t);
168 vk_specialization_map_entries_.append(vk_specialization_map_entry);
169 }
170 vk_specialization_info_.dataSize = specialization_constants.size() * sizeof(uint32_t);
171 vk_specialization_info_.pData = specialization_constants.data();
172 vk_specialization_info_.mapEntryCount = specialization_constants.size();
173 vk_specialization_info_.pMapEntries = vk_specialization_map_entries_.data();
174 return &vk_specialization_info_;
175}
176
177void VKPipelinePool::specialization_info_reset()
178{
179 vk_specialization_info_.dataSize = 0;
180 vk_specialization_info_.pData = nullptr;
181 vk_specialization_info_.mapEntryCount = 0;
182 vk_specialization_info_.pMapEntries = nullptr;
183}
184
186 const bool is_static_shader,
187 VkPipeline vk_pipeline_base)
188{
189 std::scoped_lock lock(mutex_);
190 const VkPipeline *found_pipeline = compute_pipelines_.lookup_ptr(compute_info);
191 if (found_pipeline) {
192 VkPipeline result = *found_pipeline;
193 BLI_assert(result != VK_NULL_HANDLE);
194 return result;
195 }
196
197 vk_compute_pipeline_create_info_.layout = compute_info.vk_pipeline_layout;
198 vk_compute_pipeline_create_info_.stage.module = compute_info.vk_shader_module;
199 vk_compute_pipeline_create_info_.basePipelineHandle = vk_pipeline_base;
200 vk_compute_pipeline_create_info_.stage.pSpecializationInfo = specialization_info_update(
201 compute_info.specialization_constants);
202
203 /* Build pipeline. */
204 VKBackend &backend = VKBackend::get();
205 VKDevice &device = backend.device;
206 if (device.extensions_get().descriptor_buffer) {
207 vk_compute_pipeline_create_info_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
208 }
209
210 VkPipeline pipeline = VK_NULL_HANDLE;
211 vkCreateComputePipelines(device.vk_handle(),
212 is_static_shader ? vk_pipeline_cache_static_ :
213 vk_pipeline_cache_non_static_,
214 1,
215 &vk_compute_pipeline_create_info_,
216 nullptr,
217 &pipeline);
218 compute_pipelines_.add(compute_info, pipeline);
219
220 /* Reset values to initial value. */
221 vk_compute_pipeline_create_info_.flags = 0;
222 vk_compute_pipeline_create_info_.layout = VK_NULL_HANDLE;
223 vk_compute_pipeline_create_info_.stage.module = VK_NULL_HANDLE;
224 vk_compute_pipeline_create_info_.stage.pSpecializationInfo = nullptr;
225 vk_compute_pipeline_create_info_.basePipelineHandle = VK_NULL_HANDLE;
226 specialization_info_reset();
227
228 return pipeline;
229}
230
232 const bool is_static_shader,
233 VkPipeline vk_pipeline_base)
234{
235 std::scoped_lock lock(mutex_);
236 graphics_info.fragment_shader.update_hash();
237 const VkPipeline *found_pipeline = graphic_pipelines_.lookup_ptr(graphics_info);
238 if (found_pipeline) {
239 VkPipeline result = *found_pipeline;
240 BLI_assert(result != VK_NULL_HANDLE);
241 return result;
242 }
243
244 /* Specialization constants */
245 VkSpecializationInfo *specialization_info = specialization_info_update(
246 graphics_info.specialization_constants);
247
248 /* Shader stages */
249 vk_graphics_pipeline_create_info_.stageCount =
250 graphics_info.pre_rasterization.vk_geometry_module == VK_NULL_HANDLE ? 2 : 3;
251 vk_pipeline_shader_stage_create_info_[0].module =
253 vk_pipeline_shader_stage_create_info_[0].pSpecializationInfo = specialization_info;
254 vk_pipeline_shader_stage_create_info_[1].module =
256 vk_pipeline_shader_stage_create_info_[1].pSpecializationInfo = specialization_info;
257 vk_pipeline_shader_stage_create_info_[2].module =
259 vk_pipeline_shader_stage_create_info_[2].pSpecializationInfo = specialization_info;
260
261 /* Input assembly */
262 vk_pipeline_input_assembly_state_create_info_.topology = graphics_info.vertex_in.vk_topology;
263 vk_pipeline_input_assembly_state_create_info_.primitiveRestartEnable =
264 ELEM(graphics_info.vertex_in.vk_topology,
265 VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
266 VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
267 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
268 VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY) ?
269 VK_FALSE :
270 VK_TRUE;
271 vk_pipeline_vertex_input_state_create_info_.pVertexAttributeDescriptions =
272 graphics_info.vertex_in.attributes.data();
273 vk_pipeline_vertex_input_state_create_info_.vertexAttributeDescriptionCount =
274 graphics_info.vertex_in.attributes.size();
275 vk_pipeline_vertex_input_state_create_info_.pVertexBindingDescriptions =
276 graphics_info.vertex_in.bindings.data();
277 vk_pipeline_vertex_input_state_create_info_.vertexBindingDescriptionCount =
278 graphics_info.vertex_in.bindings.size();
279
280 /* Rasterization state */
281 vk_pipeline_rasterization_state_create_info_.frontFace = graphics_info.state.invert_facing ?
282 VK_FRONT_FACE_COUNTER_CLOCKWISE :
283 VK_FRONT_FACE_CLOCKWISE;
284 vk_pipeline_rasterization_state_create_info_.cullMode = to_vk_cull_mode_flags(
285 static_cast<GPUFaceCullTest>(graphics_info.state.culling_test));
286 if (graphics_info.state.shadow_bias) {
287 vk_pipeline_rasterization_state_create_info_.depthBiasEnable = VK_TRUE;
288 vk_pipeline_rasterization_state_create_info_.depthBiasSlopeFactor = 2.0f;
289 vk_pipeline_rasterization_state_create_info_.depthBiasConstantFactor = 1.0f;
290 vk_pipeline_rasterization_state_create_info_.depthBiasClamp = 0.0f;
291 }
292 else {
293 vk_pipeline_rasterization_state_create_info_.depthBiasEnable = VK_FALSE;
294 }
295 vk_pipeline_rasterization_state_create_info_.frontFace = graphics_info.state.invert_facing ?
296 VK_FRONT_FACE_COUNTER_CLOCKWISE :
297 VK_FRONT_FACE_CLOCKWISE;
298 vk_pipeline_rasterization_provoking_vertex_state_info_.provokingVertexMode =
299 graphics_info.state.provoking_vert == GPU_VERTEX_LAST ?
300 VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
301 VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
302
303 /* Dynamic state */
304 const bool is_line_topology = ELEM(graphics_info.vertex_in.vk_topology,
305 VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
306 VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
307 VK_PRIMITIVE_TOPOLOGY_LINE_STRIP);
308 vk_pipeline_dynamic_state_create_info_.dynamicStateCount = is_line_topology ?
309 vk_dynamic_states_.size() :
310 vk_dynamic_states_.size() - 1;
311 vk_pipeline_dynamic_state_create_info_.pDynamicStates = vk_dynamic_states_.data();
312
313 /* Viewport state */
314 vk_pipeline_viewport_state_create_info_.pViewports = nullptr;
315 vk_pipeline_viewport_state_create_info_.viewportCount =
316 graphics_info.fragment_shader.viewports.size();
317 vk_pipeline_viewport_state_create_info_.pScissors = nullptr;
318 vk_pipeline_viewport_state_create_info_.scissorCount =
319 graphics_info.fragment_shader.scissors.size();
320
321 /* Color blending */
322 const VKExtensions &extensions = VKBackend::get().device.extensions_get();
323 {
324 VkPipelineColorBlendStateCreateInfo &cb = vk_pipeline_color_blend_state_create_info_;
325 VkPipelineColorBlendAttachmentState &att_state =
326 vk_pipeline_color_blend_attachment_state_template_;
327
328 att_state.blendEnable = VK_TRUE;
329 att_state.alphaBlendOp = VK_BLEND_OP_ADD;
330 att_state.colorBlendOp = VK_BLEND_OP_ADD;
331 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_DST_ALPHA;
332 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
333 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
334 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
335 att_state.colorWriteMask = 0;
336 cb.blendConstants[0] = 1.0f;
337 cb.blendConstants[1] = 1.0f;
338 cb.blendConstants[2] = 1.0f;
339 cb.blendConstants[3] = 1.0f;
340
341 switch (graphics_info.state.blend) {
342 default:
343 case GPU_BLEND_ALPHA:
344 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
345 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
346 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
347 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
348 break;
349
351 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
352 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
353 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
354 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
355 break;
356
358 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
359 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
360 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
361 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
362 break;
363
366 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
367 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
368 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
369 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
370 break;
371
373 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_DST_COLOR;
374 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
375 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_DST_ALPHA;
376 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
377 break;
378
379 case GPU_BLEND_INVERT:
380 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
381 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
382 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
383 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
384 break;
385
386 case GPU_BLEND_OIT:
387 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
388 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
389 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
390 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
391 break;
392
394 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
395 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
396 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
397 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
398 break;
399
401 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
402 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
403 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
404 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
405 break;
406
407 case GPU_BLEND_CUSTOM:
408 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
409 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_SRC1_COLOR;
410 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
411 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_SRC1_ALPHA;
412 break;
413
415 att_state.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
416 att_state.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
417 att_state.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
418 att_state.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
419 break;
420 }
421
422 if (graphics_info.state.blend == GPU_BLEND_SUBTRACT) {
423 att_state.alphaBlendOp = VK_BLEND_OP_REVERSE_SUBTRACT;
424 att_state.colorBlendOp = VK_BLEND_OP_REVERSE_SUBTRACT;
425 }
426 else {
427 att_state.alphaBlendOp = VK_BLEND_OP_ADD;
428 att_state.colorBlendOp = VK_BLEND_OP_ADD;
429 }
430
431 if (graphics_info.state.blend != GPU_BLEND_NONE) {
432 att_state.blendEnable = VK_TRUE;
433 }
434 else {
435 att_state.blendEnable = VK_FALSE;
436 }
437
438 /* Adjust the template with the color components in the write mask. */
439 if ((graphics_info.state.write_mask & GPU_WRITE_RED) != 0) {
440 att_state.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
441 }
442 if ((graphics_info.state.write_mask & GPU_WRITE_GREEN) != 0) {
443 att_state.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
444 }
445 if ((graphics_info.state.write_mask & GPU_WRITE_BLUE) != 0) {
446 att_state.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
447 }
448 if ((graphics_info.state.write_mask & GPU_WRITE_ALPHA) != 0) {
449 att_state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
450 }
451
452 /* Logic ops. */
453 if (graphics_info.state.logic_op_xor && extensions.logic_ops) {
454 cb.logicOpEnable = VK_TRUE;
455 cb.logicOp = VK_LOGIC_OP_XOR;
456 }
457
458 vk_pipeline_color_blend_attachment_states_.clear();
459 vk_pipeline_color_blend_attachment_states_.append_n_times(
460 vk_pipeline_color_blend_attachment_state_template_,
461 graphics_info.fragment_out.color_attachment_size);
462 vk_pipeline_color_blend_state_create_info_.attachmentCount =
463 vk_pipeline_color_blend_attachment_states_.size();
464 vk_pipeline_color_blend_state_create_info_.pAttachments =
465 vk_pipeline_color_blend_attachment_states_.data();
466 }
467
468 if (graphics_info.fragment_out.depth_attachment_format != VK_FORMAT_UNDEFINED) {
469 vk_graphics_pipeline_create_info_.pDepthStencilState =
470 &vk_pipeline_depth_stencil_state_create_info_;
471 vk_pipeline_depth_stencil_state_create_info_.depthWriteEnable =
472 (graphics_info.state.write_mask & GPU_WRITE_DEPTH) ? VK_TRUE : VK_FALSE;
473
474 vk_pipeline_depth_stencil_state_create_info_.depthTestEnable = VK_TRUE;
475 switch (graphics_info.state.depth_test) {
476 case GPU_DEPTH_LESS:
477 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp = VK_COMPARE_OP_LESS;
478 break;
480 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
481 break;
482 case GPU_DEPTH_EQUAL:
483 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp = VK_COMPARE_OP_EQUAL;
484 break;
486 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp = VK_COMPARE_OP_GREATER;
487 break;
489 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp =
490 VK_COMPARE_OP_GREATER_OR_EQUAL;
491 break;
492 case GPU_DEPTH_ALWAYS:
493 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp = VK_COMPARE_OP_ALWAYS;
494 break;
495 case GPU_DEPTH_NONE:
496 vk_pipeline_depth_stencil_state_create_info_.depthTestEnable = VK_FALSE;
497 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp = VK_COMPARE_OP_NEVER;
498 break;
499 }
500 }
501
502 if (graphics_info.fragment_out.stencil_attachment_format != VK_FORMAT_UNDEFINED) {
503 vk_graphics_pipeline_create_info_.pDepthStencilState =
504 &vk_pipeline_depth_stencil_state_create_info_;
505
506 switch (graphics_info.state.stencil_test) {
508 vk_pipeline_depth_stencil_state_create_info_.stencilTestEnable = VK_TRUE;
509 vk_pipeline_depth_stencil_state_create_info_.front.compareOp = VK_COMPARE_OP_NOT_EQUAL;
510 break;
512 vk_pipeline_depth_stencil_state_create_info_.stencilTestEnable = VK_TRUE;
513 vk_pipeline_depth_stencil_state_create_info_.front.compareOp = VK_COMPARE_OP_EQUAL;
514 break;
516 vk_pipeline_depth_stencil_state_create_info_.stencilTestEnable = VK_TRUE;
517 vk_pipeline_depth_stencil_state_create_info_.front.compareOp = VK_COMPARE_OP_ALWAYS;
518 break;
519 case GPU_STENCIL_NONE:
520 vk_pipeline_depth_stencil_state_create_info_.stencilTestEnable = VK_FALSE;
521 vk_pipeline_depth_stencil_state_create_info_.front.compareOp = VK_COMPARE_OP_ALWAYS;
522 break;
523 }
524
525 vk_pipeline_depth_stencil_state_create_info_.front.compareMask =
527 vk_pipeline_depth_stencil_state_create_info_.front.reference =
528 graphics_info.mutable_state.stencil_reference;
529 vk_pipeline_depth_stencil_state_create_info_.front.writeMask =
530 graphics_info.mutable_state.stencil_write_mask;
531
532 switch (graphics_info.state.stencil_op) {
534 vk_pipeline_depth_stencil_state_create_info_.front.failOp = VK_STENCIL_OP_KEEP;
535 vk_pipeline_depth_stencil_state_create_info_.front.passOp = VK_STENCIL_OP_REPLACE;
536 vk_pipeline_depth_stencil_state_create_info_.front.depthFailOp = VK_STENCIL_OP_KEEP;
537 vk_pipeline_depth_stencil_state_create_info_.back =
538 vk_pipeline_depth_stencil_state_create_info_.front;
539 break;
540
542 vk_pipeline_depth_stencil_state_create_info_.front.failOp = VK_STENCIL_OP_KEEP;
543 vk_pipeline_depth_stencil_state_create_info_.front.passOp =
544 VK_STENCIL_OP_DECREMENT_AND_WRAP;
545 vk_pipeline_depth_stencil_state_create_info_.front.depthFailOp = VK_STENCIL_OP_KEEP;
546 vk_pipeline_depth_stencil_state_create_info_.back =
547 vk_pipeline_depth_stencil_state_create_info_.front;
548 vk_pipeline_depth_stencil_state_create_info_.back.passOp =
549 VK_STENCIL_OP_INCREMENT_AND_WRAP;
550 break;
551
553 vk_pipeline_depth_stencil_state_create_info_.front.failOp = VK_STENCIL_OP_KEEP;
554 vk_pipeline_depth_stencil_state_create_info_.front.passOp = VK_STENCIL_OP_KEEP;
555 vk_pipeline_depth_stencil_state_create_info_.front.depthFailOp =
556 VK_STENCIL_OP_INCREMENT_AND_WRAP;
557 vk_pipeline_depth_stencil_state_create_info_.back =
558 vk_pipeline_depth_stencil_state_create_info_.front;
559 vk_pipeline_depth_stencil_state_create_info_.back.depthFailOp =
560 VK_STENCIL_OP_DECREMENT_AND_WRAP;
561 break;
562
564 default:
565 vk_pipeline_depth_stencil_state_create_info_.front.failOp = VK_STENCIL_OP_KEEP;
566 vk_pipeline_depth_stencil_state_create_info_.front.passOp = VK_STENCIL_OP_KEEP;
567 vk_pipeline_depth_stencil_state_create_info_.front.depthFailOp = VK_STENCIL_OP_KEEP;
568 vk_pipeline_depth_stencil_state_create_info_.back =
569 vk_pipeline_depth_stencil_state_create_info_.front;
570 break;
571 }
572 }
573
574 /* VK_KHR_dynamic_rendering */
575 vk_pipeline_rendering_create_info_.depthAttachmentFormat =
577 vk_pipeline_rendering_create_info_.stencilAttachmentFormat =
579 vk_pipeline_rendering_create_info_.colorAttachmentCount =
581 vk_pipeline_rendering_create_info_.pColorAttachmentFormats =
583
584 /* Common values */
585 vk_graphics_pipeline_create_info_.layout = graphics_info.vk_pipeline_layout;
586 /* TODO: based on `vk_pipeline_base` we should update the flags. */
587 vk_graphics_pipeline_create_info_.basePipelineHandle = vk_pipeline_base;
588
589 /* Build pipeline. */
590 VKBackend &backend = VKBackend::get();
591 VKDevice &device = backend.device;
592 if (device.extensions_get().descriptor_buffer) {
593 vk_graphics_pipeline_create_info_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
594 }
595
596 VkPipeline pipeline = VK_NULL_HANDLE;
597 vkCreateGraphicsPipelines(device.vk_handle(),
598 is_static_shader ? vk_pipeline_cache_static_ :
599 vk_pipeline_cache_non_static_,
600 1,
601 &vk_graphics_pipeline_create_info_,
602 nullptr,
603 &pipeline);
604 graphic_pipelines_.add(graphics_info, pipeline);
605
606 /* Reset values to initial value. */
607 specialization_info_reset();
608 vk_graphics_pipeline_create_info_.flags = 0;
609 vk_graphics_pipeline_create_info_.stageCount = 0;
610 vk_graphics_pipeline_create_info_.layout = VK_NULL_HANDLE;
611 vk_graphics_pipeline_create_info_.basePipelineHandle = VK_NULL_HANDLE;
612 for (VkPipelineShaderStageCreateInfo &info :
613 MutableSpan<VkPipelineShaderStageCreateInfo>(vk_pipeline_shader_stage_create_info_, 3))
614 {
615 info.module = VK_NULL_HANDLE;
616 info.pSpecializationInfo = nullptr;
617 }
618 vk_pipeline_input_assembly_state_create_info_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
619 vk_pipeline_input_assembly_state_create_info_.primitiveRestartEnable = VK_TRUE;
620 vk_pipeline_vertex_input_state_create_info_.pVertexAttributeDescriptions = nullptr;
621 vk_pipeline_vertex_input_state_create_info_.vertexAttributeDescriptionCount = 0;
622 vk_pipeline_vertex_input_state_create_info_.pVertexBindingDescriptions = nullptr;
623 vk_pipeline_vertex_input_state_create_info_.vertexBindingDescriptionCount = 0;
624 vk_pipeline_rasterization_state_create_info_.frontFace = VK_FRONT_FACE_CLOCKWISE;
625 vk_pipeline_rasterization_state_create_info_.cullMode = VK_CULL_MODE_NONE;
626 vk_pipeline_rasterization_state_create_info_.depthBiasEnable = VK_FALSE;
627 vk_pipeline_rasterization_state_create_info_.depthBiasSlopeFactor = 0.0f;
628 vk_pipeline_rasterization_state_create_info_.depthBiasConstantFactor = 0.0f;
629 vk_pipeline_rasterization_state_create_info_.depthBiasClamp = 0.0f;
630 vk_pipeline_rasterization_state_create_info_.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
631 vk_pipeline_rasterization_provoking_vertex_state_info_.provokingVertexMode =
632 VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
633 vk_pipeline_viewport_state_create_info_.pScissors = nullptr;
634 vk_pipeline_viewport_state_create_info_.scissorCount = 0;
635 vk_pipeline_viewport_state_create_info_.pViewports = nullptr;
636 vk_pipeline_viewport_state_create_info_.viewportCount = 0;
637 vk_pipeline_color_blend_state_create_info_.attachmentCount = 0;
638 vk_pipeline_color_blend_state_create_info_.logicOpEnable = VK_FALSE;
639 vk_pipeline_color_blend_state_create_info_.pAttachments = nullptr;
640 vk_pipeline_rendering_create_info_.colorAttachmentCount = 0;
641 vk_pipeline_rendering_create_info_.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
642 vk_pipeline_rendering_create_info_.pColorAttachmentFormats = nullptr;
643 vk_pipeline_rendering_create_info_.stencilAttachmentFormat = VK_FORMAT_UNDEFINED;
644 vk_pipeline_depth_stencil_state_create_info_.depthTestEnable = VK_FALSE;
645 vk_pipeline_depth_stencil_state_create_info_.depthWriteEnable = VK_FALSE;
646 vk_pipeline_depth_stencil_state_create_info_.depthCompareOp = VK_COMPARE_OP_NEVER;
647 vk_pipeline_depth_stencil_state_create_info_.stencilTestEnable = VK_FALSE;
648 vk_pipeline_depth_stencil_state_create_info_.front = {};
649 vk_pipeline_depth_stencil_state_create_info_.back = {};
650 vk_graphics_pipeline_create_info_.pDepthStencilState = nullptr;
651
652 return pipeline;
653}
654
655void VKPipelinePool::discard(VKDiscardPool &discard_pool, VkPipelineLayout vk_pipeline_layout)
656{
657 std::scoped_lock lock(mutex_);
658 compute_pipelines_.remove_if([&](auto item) {
659 if (item.key.vk_pipeline_layout == vk_pipeline_layout) {
660 discard_pool.discard_pipeline(item.value);
661 return true;
662 }
663 return false;
664 });
665 graphic_pipelines_.remove_if([&](auto item) {
666 if (item.key.vk_pipeline_layout == vk_pipeline_layout) {
667 discard_pool.discard_pipeline(item.value);
668 return true;
669 }
670 return false;
671 });
672}
673
675{
676 std::scoped_lock lock(mutex_);
677 VKDevice &device = VKBackend::get().device;
678 for (VkPipeline &vk_pipeline : graphic_pipelines_.values()) {
679 vkDestroyPipeline(device.vk_handle(), vk_pipeline, nullptr);
680 }
681 graphic_pipelines_.clear();
682 for (VkPipeline &vk_pipeline : compute_pipelines_.values()) {
683 vkDestroyPipeline(device.vk_handle(), vk_pipeline, nullptr);
684 }
685 compute_pipelines_.clear();
686
687 vkDestroyPipelineCache(device.vk_handle(), vk_pipeline_cache_static_, nullptr);
688 vkDestroyPipelineCache(device.vk_handle(), vk_pipeline_cache_non_static_, nullptr);
689}
690
691/* -------------------------------------------------------------------- */
694
695#ifdef WITH_BUILDINFO
696struct VKPipelineCachePrefixHeader {
697 /* `BC` stands for "Blender Cache" + 2 bytes for file versioning. */
698 uint32_t magic = 0xBC00;
699 uint32_t blender_version = BLENDER_VERSION;
700 uint32_t blender_version_patch = BLENDER_VERSION_PATCH;
701 char commit_hash[8];
702 uint32_t data_size;
703 uint32_t vendor_id;
704 uint32_t device_id;
705 uint32_t driver_version;
706 uint8_t pipeline_cache_uuid[VK_UUID_SIZE];
707
708 VKPipelineCachePrefixHeader()
709 {
710 const VKDevice &device = VKBackend::get().device;
711 data_size = 0;
712 const VkPhysicalDeviceProperties &properties = device.physical_device_properties_get();
713 vendor_id = properties.vendorID;
714 device_id = properties.deviceID;
715 driver_version = properties.driverVersion;
716 memcpy(&pipeline_cache_uuid, &properties.pipelineCacheUUID, VK_UUID_SIZE);
717
718 memset(commit_hash, 0, sizeof(commit_hash));
719 STRNCPY(commit_hash, build_hash);
720 }
721};
722
723static std::string pipeline_cache_filepath_get()
724{
725 static char tmp_dir_buffer[1024];
726 BKE_appdir_folder_caches(tmp_dir_buffer, sizeof(tmp_dir_buffer));
727
728 std::string cache_dir = std::string(tmp_dir_buffer) + "vk-pipeline-cache" + SEP_STR;
729 BLI_dir_create_recursive(cache_dir.c_str());
730 std::string cache_file = cache_dir + "static.bin";
731 return cache_file;
732}
733#endif
734
736{
737#ifdef WITH_BUILDINFO
738 /* Don't read the shader cache when GPU debugging is enabled. When enabled we use different
739 * shaders and compilation settings. Previous generated pipelines will not be used. */
740 if (bool(G.debug & G_DEBUG_GPU)) {
741 return;
742 }
743
744 std::string cache_file = pipeline_cache_filepath_get();
745 if (!BLI_exists(cache_file.c_str())) {
746 return;
747 }
748
749 /* Prevent old cache files from being deleted if they're still being used. */
750 BLI_file_touch(cache_file.c_str());
751 /* Read cached binary. */
752 fstream file(cache_file, std::ios::binary | std::ios::in | std::ios::ate);
753 std::streamsize data_size = file.tellg();
754 file.seekg(0, std::ios::beg);
755 void *buffer = MEM_mallocN(data_size, __func__);
756 file.read(reinterpret_cast<char *>(buffer), data_size);
757 file.close();
758
759 /* Validate the prefix header. */
760 VKPipelineCachePrefixHeader prefix;
761 VKPipelineCachePrefixHeader &read_prefix = *static_cast<VKPipelineCachePrefixHeader *>(buffer);
762 prefix.data_size = read_prefix.data_size;
763 if (memcmp(&read_prefix, &prefix, sizeof(VKPipelineCachePrefixHeader)) != 0) {
764 /* Headers are different, most likely the cache will not work and potentially crash the driver.
765 * [https://medium.com/@zeuxcg/creating-a-robust-pipeline-cache-with-vulkan-961d09416cda]
766 */
767 MEM_freeN(buffer);
768 CLOG_INFO(&LOG,
769 "Pipeline cache on disk [%s] is ignored as it was written by a different driver or "
770 "Blender version. Cache will be overwritten when exiting.",
771 cache_file.c_str());
772 return;
773 }
774
775 CLOG_INFO(&LOG, "Initialize static pipeline cache from disk [%s].", cache_file.c_str());
776 VKDevice &device = VKBackend::get().device;
777 VkPipelineCacheCreateInfo create_info = {};
778 create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
779 create_info.initialDataSize = read_prefix.data_size;
780 create_info.pInitialData = static_cast<uint8_t *>(buffer) + sizeof(VKPipelineCachePrefixHeader);
781 VkPipelineCache vk_pipeline_cache = VK_NULL_HANDLE;
782 vkCreatePipelineCache(device.vk_handle(), &create_info, nullptr, &vk_pipeline_cache);
783 MEM_freeN(buffer);
784
785 vkMergePipelineCaches(device.vk_handle(), vk_pipeline_cache_static_, 1, &vk_pipeline_cache);
786 vkDestroyPipelineCache(device.vk_handle(), vk_pipeline_cache, nullptr);
787#endif
788}
789
791{
792#ifdef WITH_BUILDINFO
793 /* Don't write the pipeline cache when GPU debugging is enabled. When enabled we use different
794 * shaders and compilation settings. Writing them to disk will clutter the pipeline cache. */
795 if (bool(G.debug & G_DEBUG_GPU)) {
796 return;
797 }
798
799 VKDevice &device = VKBackend::get().device;
800 size_t data_size;
801 vkGetPipelineCacheData(device.vk_handle(), vk_pipeline_cache_static_, &data_size, nullptr);
802 void *buffer = MEM_mallocN(data_size, __func__);
803 vkGetPipelineCacheData(device.vk_handle(), vk_pipeline_cache_static_, &data_size, buffer);
804
805 std::string cache_file = pipeline_cache_filepath_get();
806 CLOG_INFO(&LOG, "Writing static pipeline cache to disk [%s].", cache_file.c_str());
807
808 fstream file(cache_file, std::ios::binary | std::ios::out);
809
810 VKPipelineCachePrefixHeader header;
811 header.data_size = data_size;
812 file.write(reinterpret_cast<char *>(&header), sizeof(VKPipelineCachePrefixHeader));
813 file.write(static_cast<char *>(buffer), data_size);
814
815 MEM_freeN(buffer);
816#endif
817}
818
820
821} // namespace blender::gpu
bool BKE_appdir_folder_caches(char *path, size_t path_maxncpy) ATTR_NONNULL(1)
Definition appdir.cc:203
#define BLENDER_VERSION_PATCH
#define BLENDER_VERSION
@ G_DEBUG_GPU
#define BLI_assert(a)
Definition BLI_assert.h:46
bool BLI_file_touch(const char *filepath) ATTR_NONNULL(1)
Definition fileops_c.cc:316
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:360
bool BLI_dir_create_recursive(const char *dirname) ATTR_NONNULL()
Definition fileops_c.cc:414
File and directory operations.
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
#define ELEM(...)
#define CLOG_INFO(clg_ref,...)
Definition CLG_log.h:190
@ GPU_DEPTH_GREATER
Definition GPU_state.hh:116
@ GPU_DEPTH_EQUAL
Definition GPU_state.hh:115
@ GPU_DEPTH_ALWAYS
Definition GPU_state.hh:112
@ GPU_DEPTH_GREATER_EQUAL
Definition GPU_state.hh:117
@ GPU_DEPTH_LESS
Definition GPU_state.hh:113
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:114
@ GPU_DEPTH_NONE
Definition GPU_state.hh:111
@ GPU_BLEND_ADDITIVE_PREMULT
Definition GPU_state.hh:90
@ GPU_BLEND_INVERT
Definition GPU_state.hh:95
@ GPU_BLEND_OIT
Definition GPU_state.hh:98
@ GPU_BLEND_MULTIPLY
Definition GPU_state.hh:91
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
@ GPU_BLEND_CUSTOM
Definition GPU_state.hh:103
@ GPU_BLEND_ADDITIVE
Definition GPU_state.hh:89
@ GPU_BLEND_SUBTRACT
Definition GPU_state.hh:92
@ GPU_BLEND_ALPHA_UNDER_PREMUL
Definition GPU_state.hh:104
@ GPU_BLEND_BACKGROUND
Definition GPU_state.hh:100
@ GPU_BLEND_ALPHA_PREMULT
Definition GPU_state.hh:88
@ GPU_BLEND_OVERLAY_MASK_FROM_ALPHA
Definition GPU_state.hh:107
@ GPU_VERTEX_LAST
Definition GPU_state.hh:142
@ GPU_STENCIL_EQUAL
Definition GPU_state.hh:123
@ GPU_STENCIL_NEQUAL
Definition GPU_state.hh:124
@ GPU_STENCIL_ALWAYS
Definition GPU_state.hh:122
@ GPU_STENCIL_NONE
Definition GPU_state.hh:121
@ GPU_WRITE_RED
Definition GPU_state.hh:18
@ GPU_WRITE_GREEN
Definition GPU_state.hh:19
@ GPU_WRITE_BLUE
Definition GPU_state.hh:20
@ GPU_WRITE_DEPTH
Definition GPU_state.hh:22
@ GPU_WRITE_ALPHA
Definition GPU_state.hh:21
GPUFaceCullTest
Definition GPU_state.hh:135
@ GPU_STENCIL_OP_COUNT_DEPTH_FAIL
Definition GPU_state.hh:132
@ GPU_STENCIL_OP_COUNT_DEPTH_PASS
Definition GPU_state.hh:131
@ GPU_STENCIL_OP_REPLACE
Definition GPU_state.hh:129
@ GPU_STENCIL_OP_NONE
Definition GPU_state.hh:128
volatile int lock
char build_hash[]
Definition bpy_app.cc:70
int64_t size() const
void append(const T &value)
T * data()
constexpr const T * data() const
Definition BLI_span.hh:215
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr bool is_empty() const
Definition BLI_span.hh:260
static VKBackend & get()
Definition vk_backend.hh:91
VkDevice vk_handle() const
Definition vk_device.hh:311
const VKExtensions & extensions_get() const
Definition vk_device.hh:371
const VkPhysicalDeviceProperties & physical_device_properties_get() const
Definition vk_device.hh:269
void discard_pipeline(VkPipeline vk_pipeline)
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)
#define LOG(level)
Definition log.h:97
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void object_label(GLenum type, GLuint object, const char *name)
Definition gl_debug.cc:329
static CLG_LogRef LOG
VkCullModeFlags to_vk_cull_mode_flags(const GPUFaceCullTest cull_test)
Definition vk_common.cc:679
Vector< shader::SpecializationConstant::Value > specialization_constants
VkPipelineLayout vk_pipeline_layout
Vector< VkVertexInputBindingDescription > bindings
Vector< VkVertexInputAttributeDescription > attributes
Vector< shader::SpecializationConstant::Value > specialization_constants
i
Definition text_draw.cc:230
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
#define SEP_STR
Definition unit.cc:39