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