Blender V4.5
vk_device.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#pragma once
10
11#include <atomic>
12
13#include "BLI_task.h"
14#include "BLI_threads.h"
15#include "BLI_utility_mixins.hh"
16#include "BLI_vector.hh"
17
20#include "vk_buffer.hh"
21#include "vk_common.hh"
22#include "vk_debug.hh"
25#include "vk_pipeline_pool.hh"
26#include "vk_resource_pool.hh"
27#include "vk_samplers.hh"
28
29namespace blender::gpu {
30class VKBackend;
31
36 bool shader_output_layer = false;
45 bool dynamic_rendering = false;
46
51
56
60 bool external_memory = false;
61
65 bool descriptor_buffer = false;
66
70 bool logic_ops = false;
71
75 bool memory_priority = false;
76
81
83 void log() const;
84};
85
86/* TODO: Split into VKWorkarounds and VKExtensions to remove the negating when an extension isn't
87 * supported. */
96
97 struct {
102 bool r8g8b8 = false;
104};
105
115 static constexpr uint32_t resource_pools_count = 5;
116
117 public:
119 pthread_t thread_id;
127 std::array<VKResourcePool, resource_pools_count> resource_pools;
128
138
139 VKThreadData(VKDevice &device, pthread_t thread_id);
140
145 {
146 if (resource_pool_index >= resource_pools.size()) {
147 return resource_pools[0];
148 }
150 }
151
154 {
157 }
158 else {
159 resource_pool_index = (resource_pool_index + 1) % resource_pools_count;
160 }
161 }
162};
163
164class VKDevice : public NonCopyable {
165 private:
167 VkInstance vk_instance_ = VK_NULL_HANDLE;
168 VkPhysicalDevice vk_physical_device_ = VK_NULL_HANDLE;
169 VkDevice vk_device_ = VK_NULL_HANDLE;
170 uint32_t vk_queue_family_ = 0;
171 VkQueue vk_queue_ = VK_NULL_HANDLE;
172 std::mutex *queue_mutex_ = nullptr;
173
174 bool is_initialized_ = false;
175
183 TaskPool *submission_pool_ = nullptr;
188 ThreadQueue *submitted_render_graphs_ = nullptr;
189 ThreadQueue *unused_render_graphs_ = nullptr;
190 VkSemaphore vk_timeline_semaphore_ = VK_NULL_HANDLE;
196 TimelineValue timeline_value_ = 0;
197
198 VKSamplers samplers_;
199 VKDescriptorSetLayouts descriptor_set_layouts_;
200
211
213 VmaAllocator mem_allocator_ = VK_NULL_HANDLE;
214
216 VkPhysicalDeviceProperties vk_physical_device_properties_ = {};
217 VkPhysicalDeviceDriverProperties vk_physical_device_driver_properties_ = {};
218 VkPhysicalDeviceIDProperties vk_physical_device_id_properties_ = {};
219 VkPhysicalDeviceMemoryProperties vk_physical_device_memory_properties_ = {};
220 VkPhysicalDeviceDescriptorBufferPropertiesEXT vk_physical_device_descriptor_buffer_properties_ =
221 {};
223 VkPhysicalDeviceFeatures vk_physical_device_features_ = {};
224 VkPhysicalDeviceVulkan11Features vk_physical_device_vulkan_11_features_ = {};
225 VkPhysicalDeviceVulkan12Features vk_physical_device_vulkan_12_features_ = {};
226 Array<VkExtensionProperties> device_extensions_;
227
229 debug::VKDebuggingTools debugging_tools_;
230
231 /* Workarounds */
232 VKWorkarounds workarounds_;
233 VKExtensions extensions_;
234
235 std::string glsl_vert_patch_;
236 std::string glsl_geom_patch_;
237 std::string glsl_frag_patch_;
238 std::string glsl_comp_patch_;
239 Vector<VKThreadData *> thread_data_;
240
241 public:
249
253 struct {
254 /* Extension: VK_KHR_dynamic_rendering */
255 PFN_vkCmdBeginRendering vkCmdBeginRendering = nullptr;
256 PFN_vkCmdEndRendering vkCmdEndRendering = nullptr;
257
258 /* Extension: VK_EXT_debug_utils */
259 PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabel = nullptr;
260 PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabel = nullptr;
261 PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectName = nullptr;
262 PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessenger = nullptr;
263 PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessenger = nullptr;
264
265 /* Extension: VK_KHR_external_memory_fd */
266 PFN_vkGetMemoryFdKHR vkGetMemoryFd = nullptr;
267
268#ifdef _WIN32
269 /* Extension: VK_KHR_external_memory_win32 */
270 PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32Handle = nullptr;
271#endif
272
273 /* Extension: VK_EXT_descriptor_buffer */
274 PFN_vkGetDescriptorSetLayoutSizeEXT vkGetDescriptorSetLayoutSize = nullptr;
275 PFN_vkGetDescriptorSetLayoutBindingOffsetEXT vkGetDescriptorSetLayoutBindingOffset = nullptr;
276 PFN_vkGetDescriptorEXT vkGetDescriptor = nullptr;
277 PFN_vkCmdBindDescriptorBuffersEXT vkCmdBindDescriptorBuffers = nullptr;
278 PFN_vkCmdSetDescriptorBufferOffsetsEXT vkCmdSetDescriptorBufferOffsets = nullptr;
279
281
282 struct {
283 /* NOTE: This attribute needs to be kept alive as it will be read by VMA when allocating from
284 * `external_memory` pool. */
285 VkExportMemoryAllocateInfoKHR external_memory_info = {
286 VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR};
287 VmaPool external_memory = VK_NULL_HANDLE;
289
290 const char *extension_name_get(int index) const
291 {
292 return device_extensions_[index].extensionName;
293 }
294
295 VkPhysicalDevice physical_device_get() const
296 {
297 return vk_physical_device_;
298 }
299
300 const VkPhysicalDeviceProperties &physical_device_properties_get() const
301 {
302 return vk_physical_device_properties_;
303 }
304
305 const VkPhysicalDeviceIDProperties &physical_device_id_properties_get() const
306 {
307 return vk_physical_device_id_properties_;
308 }
309
310 inline const VkPhysicalDeviceDescriptorBufferPropertiesEXT &
312 {
313 return vk_physical_device_descriptor_buffer_properties_;
314 }
315
316 const VkPhysicalDeviceFeatures &physical_device_features_get() const
317 {
318 return vk_physical_device_features_;
319 }
320
321 const VkPhysicalDeviceVulkan11Features &physical_device_vulkan_11_features_get() const
322 {
323 return vk_physical_device_vulkan_11_features_;
324 }
325
326 const VkPhysicalDeviceVulkan12Features &physical_device_vulkan_12_features_get() const
327 {
328 return vk_physical_device_vulkan_12_features_;
329 }
330
331 VkInstance instance_get() const
332 {
333 return vk_instance_;
334 };
335
336 VkDevice vk_handle() const
337 {
338 return vk_device_;
339 }
340
341 uint32_t queue_family_get() const
342 {
343 return vk_queue_family_;
344 }
345
346 VmaAllocator mem_allocator_get() const
347 {
348 return mem_allocator_;
349 }
350
352 {
353 return descriptor_set_layouts_;
354 }
355
357 {
358 return debugging_tools_;
359 }
360
362 {
363 return debugging_tools_;
364 }
365
366 const VKSamplers &samplers() const
367 {
368 return samplers_;
369 }
370
371 void init(void *ghost_context);
372 void reinit();
373 void deinit();
374 bool is_initialized() const
375 {
376 return is_initialized_;
377 }
378
381 std::string vendor_name() const;
382 std::string driver_version() const;
383
390 bool supports_extension(const char *extension_name) const;
391
393 {
394 return workarounds_;
395 }
396 inline const VKExtensions &extensions_get() const
397 {
398 return extensions_;
399 }
400
401 const char *glsl_vertex_patch_get() const;
402 const char *glsl_geometry_patch_get() const;
403 const char *glsl_fragment_patch_get() const;
404 const char *glsl_compute_patch_get() const;
405 void init_glsl_patch();
406
407 /* -------------------------------------------------------------------- */
410 static void submission_runner(TaskPool *__restrict pool, void *task_data);
412
414 VKDiscardPool &context_discard_pool,
415 bool submit_to_device,
416 bool wait_for_completion,
417 VkPipelineStageFlags wait_dst_stage_mask,
418 VkSemaphore wait_semaphore,
419 VkSemaphore signal_semaphore,
420 VkFence signal_fence);
421 void wait_for_timeline(TimelineValue timeline);
422 void wait_queue_idle();
423
428 {
429 BLI_assert(vk_timeline_semaphore_ != VK_NULL_HANDLE);
430 TimelineValue current_timeline;
431 vkGetSemaphoreCounterValue(vk_device_, vk_timeline_semaphore_, &current_timeline);
432 return current_timeline;
433 }
434
436
437 /* -------------------------------------------------------------------- */
440
445
446#if 0
461 VKDiscardPool &discard_pool_for_current_thread(bool thread_safe = false);
462#endif
463
464 void context_register(VKContext &context);
465 void context_unregister(VKContext &context);
467
468 void memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) const;
469 static void debug_print(std::ostream &os, const VKDiscardPool &discard_pool);
470 void debug_print();
471
473
474 private:
475 void init_physical_device_properties();
476 void init_physical_device_memory_properties();
477 void init_physical_device_features();
478 void init_physical_device_extensions();
479 void init_debug_callbacks();
480 void init_memory_allocator();
481 void init_submission_pool();
482 void deinit_submission_pool();
486 void init_functions();
487
491 void init_dummy_buffer();
492
493 /* During initialization the backend requires access to update the workarounds. */
494 friend VKBackend;
495};
496
497} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
eGPUDriverType
eGPUDeviceType
void init()
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
uint32_t queue_family_get() const
Definition vk_device.hh:341
VKPipelinePool pipelines
Definition vk_device.hh:246
PFN_vkGetDescriptorSetLayoutBindingOffsetEXT vkGetDescriptorSetLayoutBindingOffset
Definition vk_device.hh:275
const char * extension_name_get(int index) const
Definition vk_device.hh:290
PFN_vkCmdBindDescriptorBuffersEXT vkCmdBindDescriptorBuffers
Definition vk_device.hh:277
render_graph::VKResourceStateTracker resources
Definition vk_device.hh:242
PFN_vkCmdSetDescriptorBufferOffsetsEXT vkCmdSetDescriptorBufferOffsets
Definition vk_device.hh:278
const VkPhysicalDeviceFeatures & physical_device_features_get() const
Definition vk_device.hh:316
PFN_vkGetMemoryFdKHR vkGetMemoryFd
Definition vk_device.hh:266
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectName
Definition vk_device.hh:261
VmaAllocator mem_allocator_get() const
Definition vk_device.hh:346
VKDescriptorSetLayouts & descriptor_set_layouts_get()
Definition vk_device.hh:351
VkDevice vk_handle() const
Definition vk_device.hh:336
bool supports_extension(const char *extension_name) const
Definition vk_device.cc:253
const VKExtensions & extensions_get() const
Definition vk_device.hh:396
const VkPhysicalDeviceProperties & physical_device_properties_get() const
Definition vk_device.hh:300
struct blender::gpu::VKDevice::@262132226121372152356051207311115003347304265036 vma_pools
const VKSamplers & samplers() const
Definition vk_device.hh:366
std::string vendor_name() const
Definition vk_device.cc:468
std::string driver_version() const
Definition vk_device.cc:495
TimelineValue submission_finished_timeline_get() const
Definition vk_device.hh:427
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessenger
Definition vk_device.hh:262
const char * glsl_geometry_patch_get() const
Definition vk_device.cc:382
render_graph::VKRenderGraph * render_graph_new()
PFN_vkGetDescriptorEXT vkGetDescriptor
Definition vk_device.hh:276
VKDiscardPool orphaned_data
Definition vk_device.hh:243
const char * glsl_fragment_patch_get() const
Definition vk_device.cc:388
VkExportMemoryAllocateInfoKHR external_memory_info
Definition vk_device.hh:285
debug::VKDebuggingTools & debugging_tools_get()
Definition vk_device.hh:356
VKThreadData & current_thread_data()
Definition vk_device.cc:520
const VkPhysicalDeviceIDProperties & physical_device_id_properties_get() const
Definition vk_device.hh:305
eGPUDriverType driver_type() const
Definition vk_device.cc:442
PFN_vkGetDescriptorSetLayoutSizeEXT vkGetDescriptorSetLayoutSize
Definition vk_device.hh:274
static void submission_runner(TaskPool *__restrict pool, void *task_data)
const debug::VKDebuggingTools & debugging_tools_get() const
Definition vk_device.hh:361
void context_register(VKContext &context)
Definition vk_device.cc:536
bool is_initialized() const
Definition vk_device.hh:374
VkPhysicalDevice physical_device_get() const
Definition vk_device.hh:295
const char * glsl_compute_patch_get() const
Definition vk_device.cc:394
const VKWorkarounds & workarounds_get() const
Definition vk_device.hh:392
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabel
Definition vk_device.hh:260
const char * glsl_vertex_patch_get() const
Definition vk_device.cc:376
VkInstance instance_get() const
Definition vk_device.hh:331
TimelineValue render_graph_submit(render_graph::VKRenderGraph *render_graph, VKDiscardPool &context_discard_pool, bool submit_to_device, bool wait_for_completion, VkPipelineStageFlags wait_dst_stage_mask, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkFence signal_fence)
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessenger
Definition vk_device.hh:263
void context_unregister(VKContext &context)
Definition vk_device.cc:541
const VkPhysicalDeviceVulkan12Features & physical_device_vulkan_12_features_get() const
Definition vk_device.hh:326
PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabel
Definition vk_device.hh:259
void memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) const
Definition vk_device.cc:563
struct blender::gpu::VKDevice::@164322360241203077355133066050124027157363067003 functions
void wait_for_timeline(TimelineValue timeline)
const VkPhysicalDeviceDescriptorBufferPropertiesEXT & physical_device_descriptor_buffer_properties_get() const
Definition vk_device.hh:311
PFN_vkCmdBeginRendering vkCmdBeginRendering
Definition vk_device.hh:255
const VkPhysicalDeviceVulkan11Features & physical_device_vulkan_11_features_get() const
Definition vk_device.hh:321
Span< std::reference_wrapper< VKContext > > contexts_get() const
Definition vk_device.cc:558
PFN_vkCmdEndRendering vkCmdEndRendering
Definition vk_device.hh:256
eGPUDeviceType device_type() const
Definition vk_device.cc:410
VKDiscardPool orphaned_data_render
Definition vk_device.hh:245
std::array< VKResourcePool, resource_pools_count > resource_pools
Definition vk_device.hh:127
VKThreadData(VKDevice &device, pthread_t thread_id)
Definition vk_device.cc:507
VKResourcePool & resource_pool_get()
Definition vk_device.hh:144
#define UINT32_MAX
uint64_t TimelineValue
Definition vk_common.hh:36
struct blender::gpu::VKWorkarounds::@250247362134102263364163314040144106045031265005 vertex_formats