38 " - [%c] shader output viewport index\n"
39 " - [%c] shader output layer\n"
40 " - [%c] fragment shader barycentric\n"
42 " - [%c] descriptor buffer\n"
43 " - [%c] dynamic rendering\n"
44 " - [%c] dynamic rendering local read\n"
45 " - [%c] dynamic rendering unused attachments\n"
46 " - [%c] external memory\n"
47 " - [%c] memory priority\n"
48 " - [%c] pageable device local memory\n"
49 " - [%c] shader stencil export",
75 deinit_submission_pool();
81 while (!thread_data_.is_empty()) {
89 descriptor_set_layouts_.deinit();
92 vmaDestroyPool(mem_allocator_,
vma_pools.external_memory);
93 vmaDestroyAllocator(mem_allocator_);
94 mem_allocator_ = VK_NULL_HANDLE;
96 while (!render_graphs_.is_empty()) {
101 debugging_tools_.deinit(vk_instance_);
103 vk_instance_ = VK_NULL_HANDLE;
104 vk_physical_device_ = VK_NULL_HANDLE;
105 vk_device_ = VK_NULL_HANDLE;
106 vk_queue_family_ = 0;
107 vk_queue_ = VK_NULL_HANDLE;
108 vk_physical_device_properties_ = {};
109 glsl_vert_patch_.clear();
110 glsl_frag_patch_.clear();
111 glsl_geom_patch_.clear();
112 glsl_comp_patch_.clear();
113 is_initialized_ =
false;
119 GHOST_VulkanHandles
handles = {};
120 GHOST_GetVulkanHandles((GHOST_ContextHandle)ghost_context, &
handles);
121 vk_instance_ =
handles.instance;
122 vk_physical_device_ =
handles.physical_device;
124 vk_queue_family_ =
handles.graphic_queue_family;
126 queue_mutex_ =
static_cast<std::mutex *
>(
handles.queue_mutex);
128 init_physical_device_extensions();
129 init_physical_device_properties();
130 init_physical_device_memory_properties();
131 init_physical_device_features();
135 init_debug_callbacks();
136 init_memory_allocator();
147 resources.use_dynamic_rendering = extensions_.dynamic_rendering;
148 resources.use_dynamic_rendering_local_read = extensions_.dynamic_rendering_local_read;
151 init_submission_pool();
152 is_initialized_ =
true;
155void VKDevice::init_functions()
157#define LOAD_FUNCTION(name) (PFN_##name) vkGetInstanceProcAddr(vk_instance_, STRINGIFY(name))
173#elif not defined(__APPLE__)
182 vkGetDescriptorSetLayoutBindingOffsetEXT);
190void VKDevice::init_debug_callbacks()
192 debugging_tools_.
init(vk_instance_);
195void VKDevice::init_physical_device_properties()
197 BLI_assert(vk_physical_device_ != VK_NULL_HANDLE);
199 VkPhysicalDeviceProperties2 vk_physical_device_properties = {};
200 vk_physical_device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
201 vk_physical_device_driver_properties_.sType =
202 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
203 vk_physical_device_id_properties_.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
204 vk_physical_device_properties.pNext = &vk_physical_device_driver_properties_;
205 vk_physical_device_driver_properties_.pNext = &vk_physical_device_id_properties_;
208 vk_physical_device_descriptor_buffer_properties_ = {
209 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_PROPERTIES_EXT};
210 vk_physical_device_descriptor_buffer_properties_.pNext =
211 vk_physical_device_driver_properties_.pNext;
212 vk_physical_device_driver_properties_.pNext =
213 &vk_physical_device_descriptor_buffer_properties_;
216 vkGetPhysicalDeviceProperties2(vk_physical_device_, &vk_physical_device_properties);
217 vk_physical_device_properties_ = vk_physical_device_properties.properties;
220void VKDevice::init_physical_device_memory_properties()
222 BLI_assert(vk_physical_device_ != VK_NULL_HANDLE);
223 vkGetPhysicalDeviceMemoryProperties(vk_physical_device_, &vk_physical_device_memory_properties_);
226void VKDevice::init_physical_device_features()
228 BLI_assert(vk_physical_device_ != VK_NULL_HANDLE);
230 VkPhysicalDeviceFeatures2 features = {};
231 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
232 vk_physical_device_vulkan_11_features_.sType =
233 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
234 vk_physical_device_vulkan_12_features_.sType =
235 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
237 features.pNext = &vk_physical_device_vulkan_11_features_;
238 vk_physical_device_vulkan_11_features_.pNext = &vk_physical_device_vulkan_12_features_;
240 vkGetPhysicalDeviceFeatures2(vk_physical_device_, &features);
241 vk_physical_device_features_ = features.features;
244void VKDevice::init_physical_device_extensions()
247 vkEnumerateDeviceExtensionProperties(vk_physical_device_,
nullptr, &
count,
nullptr);
248 device_extensions_ = Array<VkExtensionProperties>(
count);
249 vkEnumerateDeviceExtensionProperties(
250 vk_physical_device_,
nullptr, &
count, device_extensions_.data());
255 for (
const VkExtensionProperties &vk_extension_properties : device_extensions_) {
256 if (
STREQ(vk_extension_properties.extensionName, extension_name)) {
263void VKDevice::init_memory_allocator()
265 VmaAllocatorCreateInfo info = {};
266 info.vulkanApiVersion = VK_API_VERSION_1_2;
267 info.physicalDevice = vk_physical_device_;
268 info.device = vk_device_;
269 info.instance = vk_instance_;
271 info.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
274 info.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT;
276 vmaCreateAllocator(&info, &mem_allocator_);
278 if (!extensions_.external_memory) {
284 VkExternalMemoryHandleTypeFlags vk_external_memory_handle_type = 0;
286 vk_external_memory_handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
288 vk_external_memory_handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
290 VkExternalMemoryImageCreateInfo external_image_create_info = {
291 VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
293 vk_external_memory_handle_type};
294 VkImageCreateInfo image_create_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
295 &external_image_create_info,
298 VK_FORMAT_R8G8B8A8_UNORM,
302 VK_SAMPLE_COUNT_1_BIT,
303 VK_IMAGE_TILING_OPTIMAL,
304 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
305 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
306 VK_IMAGE_USAGE_SAMPLED_BIT,
307 VK_SHARING_MODE_EXCLUSIVE,
310 VK_IMAGE_LAYOUT_UNDEFINED};
311 VmaAllocationCreateInfo allocation_create_info = {};
312 allocation_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
313 allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO;
315 vmaFindMemoryTypeIndexForImageInfo(
316 mem_allocator_, &image_create_info, &allocation_create_info, &memory_type_index);
318 vma_pools.external_memory_info.handleTypes = vk_external_memory_handle_type;
319 VmaPoolCreateInfo pool_create_info = {};
320 pool_create_info.memoryTypeIndex = memory_type_index;
321 pool_create_info.pMemoryAllocateNext = &
vma_pools.external_memory_info;
322 pool_create_info.priority = 1.0f;
323 vmaCreatePool(mem_allocator_, &pool_create_info, &
vma_pools.external_memory);
326void VKDevice::init_dummy_buffer()
329 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
330 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
331 VkMemoryPropertyFlags(0),
332 VmaAllocationCreateFlags(0),
337 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
343 std::stringstream ss;
345 ss <<
"#version 450\n";
347 ss <<
"#extension GL_ARB_shader_draw_parameters : enable\n";
348 ss <<
"#define GPU_ARB_shader_draw_parameters\n";
349 ss <<
"#define gpu_BaseInstance (gl_BaseInstanceARB)\n";
351 ss <<
"#define GPU_ARB_clip_control\n";
353 ss <<
"#define gl_VertexID gl_VertexIndex\n";
354 ss <<
"#define gpu_InstanceIndex (gl_InstanceIndex)\n";
355 ss <<
"#define gl_InstanceID (gpu_InstanceIndex - gpu_BaseInstance)\n";
357 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
359 ss <<
"#extension GL_ARB_shader_stencil_export: enable\n";
360 ss <<
"#define GPU_ARB_shader_stencil_export 1\n";
362 if (extensions_.fragment_shader_barycentric) {
363 ss <<
"#extension GL_EXT_fragment_shader_barycentric : require\n";
364 ss <<
"#define gpu_BaryCoord gl_BaryCoordEXT\n";
365 ss <<
"#define gpu_BaryCoordNoPersp gl_BaryCoordNoPerspEXT\n";
379 return glsl_vert_patch_.c_str();
385 return glsl_geom_patch_.c_str();
391 return glsl_frag_patch_.c_str();
397 return glsl_comp_patch_.c_str();
412 switch (vk_physical_device_driver_properties_.driverID) {
413 case VK_DRIVER_ID_AMD_PROPRIETARY:
414 case VK_DRIVER_ID_AMD_OPEN_SOURCE:
415 case VK_DRIVER_ID_MESA_RADV:
418 case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
419 case VK_DRIVER_ID_MESA_NVK:
422 case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:
423 case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
426 case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
429 case VK_DRIVER_ID_MOLTENVK:
432 case VK_DRIVER_ID_MESA_LLVMPIPE:
444 switch (vk_physical_device_driver_properties_.driverID) {
445 case VK_DRIVER_ID_AMD_PROPRIETARY:
446 case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:
447 case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
448 case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
451 case VK_DRIVER_ID_MOLTENVK:
452 case VK_DRIVER_ID_AMD_OPEN_SOURCE:
453 case VK_DRIVER_ID_MESA_RADV:
454 case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
455 case VK_DRIVER_ID_MESA_NVK:
458 case VK_DRIVER_ID_MESA_LLVMPIPE:
471 if (vk_physical_device_properties_.vendorID < 0x10000) {
472 switch (vk_physical_device_properties_.vendorID) {
475 return "Advanced Micro Devices";
477 return "NVIDIA Corporation";
479 return "Intel Corporation";
483 return std::to_string(vk_physical_device_properties_.vendorID);
491 return std::to_string(vk_physical_device_properties_.vendorID);
497 return StringRefNull(vk_physical_device_driver_properties_.driverName) +
" " +
498 StringRefNull(vk_physical_device_driver_properties_.driverInfo);
510 resource_pool.init(device);
523 pthread_t current_thread_id = pthread_self();
526 if (pthread_equal(thread_data->thread_id, current_thread_id)) {
532 thread_data_.append(thread_data);
538 contexts_.append(std::reference_wrapper(context));
543 if (context.render_graph_.has_value()) {
545 context.render_graph_.reset();
547 "Unregistering a context that still has an unsubmitted render graph.");
553 orphaned_data.move_data(context.discard_pool, timeline_value_ + 1);
556 contexts_.remove(contexts_.first_index_of(std::reference_wrapper(context)));
565 VmaBudget budgets[VK_MAX_MEMORY_HEAPS];
567 VkDeviceSize total_mem = 0;
568 VkDeviceSize used_mem = 0;
570 for (
int memory_heap_index :
IndexRange(vk_physical_device_memory_properties_.memoryHeapCount)) {
571 const VkMemoryHeap &memory_heap =
572 vk_physical_device_memory_properties_.memoryHeaps[memory_heap_index];
573 const VmaBudget &budget = budgets[memory_heap_index];
576 if (!
bool(memory_heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)) {
580 total_mem += memory_heap.size;
581 used_mem += budget.usage;
584 *r_total_mem_kb = int(total_mem / 1024);
585 *r_free_mem_kb = int((total_mem - used_mem) / 1024);
597 discard_pool.image_views_.
is_empty() && discard_pool.buffer_views_.
is_empty() &&
598 discard_pool.shader_modules_.
is_empty() && discard_pool.pipeline_layouts_.
is_empty() &&
599 discard_pool.descriptor_pools_.
is_empty())
603 os <<
" Discardable resources: ";
604 if (!discard_pool.images_.
is_empty()) {
605 os <<
"VkImage=" << discard_pool.images_.
size() <<
" ";
607 if (!discard_pool.image_views_.
is_empty()) {
608 os <<
"VkImageView=" << discard_pool.image_views_.
size() <<
" ";
610 if (!discard_pool.buffers_.
is_empty()) {
611 os <<
"VkBuffer=" << discard_pool.buffers_.
size() <<
" ";
613 if (!discard_pool.buffer_views_.
is_empty()) {
614 os <<
"VkBufferViews=" << discard_pool.buffer_views_.
size() <<
" ";
616 if (!discard_pool.shader_modules_.
is_empty()) {
617 os <<
"VkShaderModule=" << discard_pool.shader_modules_.
size() <<
" ";
619 if (!discard_pool.pipeline_layouts_.
is_empty()) {
620 os <<
"VkPipelineLayout=" << discard_pool.pipeline_layouts_.
size() <<
" ";
622 if (!discard_pool.descriptor_pools_.
is_empty()) {
623 os <<
"VkDescriptorPool=" << discard_pool.descriptor_pools_.
size();
631 "VKDevice::debug_print can only be called from the main thread.");
633 std::ostream &os = std::cout;
636 os <<
" Graphics: " <<
pipelines.graphic_pipelines_.size() <<
"\n";
637 os <<
" Compute: " <<
pipelines.compute_pipelines_.size() <<
"\n";
638 os <<
"Descriptor sets\n";
639 os <<
" VkDescriptorSetLayouts: " << descriptor_set_layouts_.size() <<
"\n";
643 const bool is_main = pthread_equal(thread_data->thread_id, pthread_self());
644 os <<
"ThreadData" << (is_main ?
" (main-thread)" :
"") <<
")\n";
645 os <<
" Rendering_depth: " << thread_data->rendering_depth <<
"\n";
646 for (
int resource_pool_index :
IndexRange(thread_data->resource_pools.size())) {
647 const bool is_active = thread_data->resource_pool_index == resource_pool_index;
648 os <<
" Resource Pool (index=" << resource_pool_index << (is_active ?
" active" :
"")
652 os <<
"Discard pool\n";
654 os <<
"Discard pool (render)\n";
658 for (
const std::reference_wrapper<VKContext> &context : contexts_) {
659 os <<
" VKContext \n";
666 os <<
"\nMemory: total=" << total_mem_kb <<
", free=" << free_mem_kb <<
"\n";
#define BLI_assert_msg(a, msg)
void BLI_thread_queue_push(ThreadQueue *queue, void *work)
int BLI_thread_is_main(void)
#define CLOG_INFO(clg_ref, level,...)
GHOST C-API function and type declarations.
bool GPU_stencil_export_support()
bool GPU_shader_draw_parameters_support()
BMesh const char void * data
static void capabilities_init(VKDevice &device)
static void platform_init(const VKDevice &device)
void init(void *ghost_context)
render_graph::VKResourceStateTracker resources
VmaAllocator mem_allocator_get() const
VkDevice vk_handle() const
bool supports_extension(const char *extension_name) const
std::string vendor_name() const
std::string driver_version() const
const char * glsl_geometry_patch_get() const
VKDiscardPool orphaned_data
const char * glsl_fragment_patch_get() const
VKThreadData & current_thread_data()
eGPUDriverType driver_type() const
void context_register(VKContext &context)
bool is_initialized() const
struct blender::gpu::VKDevice::@357253123303341036353224041006002133032155310370 functions
const char * glsl_compute_patch_get() const
const char * glsl_vertex_patch_get() const
void context_unregister(VKContext &context)
struct blender::gpu::VKDevice::@042163346115313254005332154330057226242036157146 vma_pools
void memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) const
Span< std::reference_wrapper< VKContext > > contexts_get() const
eGPUDeviceType device_type() const
VKDiscardPool orphaned_data_render
std::array< VKResourcePool, resource_pools_count > resource_pools
VKThreadData(VKDevice &device, pthread_t thread_id)
char datatoc_glsl_shader_defines_glsl[]
void object_label(GLenum type, GLuint object, const char *name)
constexpr int32_t PCI_ID_NVIDIA
constexpr int32_t PCI_ID_INTEL
constexpr int32_t PCI_ID_ATI
constexpr int32_t PCI_ID_AMD
constexpr int32_t PCI_ID_APPLE
MatBase< float, 4, 4 > float4x4
bool dynamic_rendering_unused_attachments
bool fragment_shader_barycentric
bool pageable_device_local_memory
bool dynamic_rendering_local_read
bool shader_output_viewport_index
#define LOAD_FUNCTION(name)