From 1af40437fe53f08bc31ac37b68e7caaecbc58e24 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 4 May 2023 09:54:30 +0200 Subject: [PATCH 1/2] Vulkan: Share Device Between Contexts Previous GHOST_ContextVK would create a logical device for each context. Blender uses multiple contexts at the same time and wasn't able to share resources between them as the logical device where different. This patch will create a single logical device and share them between multiple contexts. This allows sharing memory/shaders between contexts and make sure that all memory allocations are freed from the device it was allocated from. Some allocations in Blender are freed when there isn't a context, this was failing in the previous implementation. We didn't noticed it before as we didn't test multiple contexts. This patch also moves device specific data structures from VKContext to VKDevice like the descriptor pools, debug layers etc. --- intern/ghost/intern/GHOST_ContextVK.cc | 666 +++++++++--------- intern/ghost/intern/GHOST_ContextVK.hh | 7 - source/blender/gpu/CMakeLists.txt | 2 + source/blender/gpu/vulkan/vk_backend.cc | 12 +- source/blender/gpu/vulkan/vk_backend.hh | 21 +- source/blender/gpu/vulkan/vk_buffer.cc | 37 +- source/blender/gpu/vulkan/vk_buffer.hh | 11 +- source/blender/gpu/vulkan/vk_context.cc | 49 +- source/blender/gpu/vulkan/vk_context.hh | 67 -- source/blender/gpu/vulkan/vk_debug.cc | 166 ++--- source/blender/gpu/vulkan/vk_debug.hh | 33 +- .../blender/gpu/vulkan/vk_descriptor_set.cc | 12 +- source/blender/gpu/vulkan/vk_device.cc | 90 +++ source/blender/gpu/vulkan/vk_device.hh | 100 +++ source/blender/gpu/vulkan/vk_framebuffer.cc | 13 +- source/blender/gpu/vulkan/vk_index_buffer.cc | 10 +- source/blender/gpu/vulkan/vk_index_buffer.hh | 2 +- source/blender/gpu/vulkan/vk_pipeline.cc | 17 +- source/blender/gpu/vulkan/vk_pipeline.hh | 3 +- source/blender/gpu/vulkan/vk_pixel_buffer.cc | 5 +- source/blender/gpu/vulkan/vk_shader.cc | 33 +- .../blender/gpu/vulkan/vk_shader_interface.cc | 5 +- .../blender/gpu/vulkan/vk_storage_buffer.cc | 17 +- .../blender/gpu/vulkan/vk_storage_buffer.hh | 2 +- source/blender/gpu/vulkan/vk_texture.cc | 21 +- .../blender/gpu/vulkan/vk_uniform_buffer.cc | 17 +- .../blender/gpu/vulkan/vk_uniform_buffer.hh | 2 +- source/blender/gpu/vulkan/vk_vertex_buffer.cc | 10 +- source/blender/gpu/vulkan/vk_vertex_buffer.hh | 2 +- 29 files changed, 774 insertions(+), 658 deletions(-) create mode 100644 source/blender/gpu/vulkan/vk_device.cc create mode 100644 source/blender/gpu/vulkan/vk_device.hh diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 85d90b15095..23a3a2dacf7 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -121,6 +122,224 @@ static bool vklayer_config_exist(const char *vk_extension_config) /* Triple buffering. */ const int MAX_FRAMES_IN_FLIGHT = 2; +/* -------------------------------------------------------------------- */ +/** \name Vulkan Device + * \{ */ + +class GHOST_DeviceVK { + public: + VkInstance instance = VK_NULL_HANDLE; + VkPhysicalDevice physical_device = VK_NULL_HANDLE; + + VkDevice device = VK_NULL_HANDLE; + + uint32_t generic_queue_family = 0; + + VkPhysicalDeviceProperties properties = {}; + VkPhysicalDeviceFeatures features = {}; + int users = 0; + + public: + GHOST_DeviceVK(VkInstance vk_instance, VkPhysicalDevice vk_physical_device) + : instance(vk_instance), physical_device(vk_physical_device) + { + vkGetPhysicalDeviceProperties(physical_device, &properties); + vkGetPhysicalDeviceFeatures(physical_device, &features); + } + ~GHOST_DeviceVK() + { + if (device != VK_NULL_HANDLE) { + vkDestroyDevice(device, NULL); + } + } + + void wait_idle() + { + if (device) { + vkDeviceWaitIdle(device); + } + } + + bool extensions_support(const vector &required_extensions) + { + uint32_t ext_count; + vkEnumerateDeviceExtensionProperties(physical_device, NULL, &ext_count, NULL); + + vector available_exts(ext_count); + vkEnumerateDeviceExtensionProperties(physical_device, NULL, &ext_count, available_exts.data()); + + for (const auto &extension_needed : required_extensions) { + bool found = false; + for (const auto &extension : available_exts) { + if (strcmp(extension_needed, extension.extensionName) == 0) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } + + void ensure_device(vector &layers_enabled, vector &extensions_device) + { + if (device != VK_NULL_HANDLE) { + return; + } + init_generic_queue_family(); + + vector queue_create_infos; + + float queue_priorities[] = {1.0f}; + VkDeviceQueueCreateInfo graphic_queue_create_info = {}; + graphic_queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + graphic_queue_create_info.queueFamilyIndex = generic_queue_family; + graphic_queue_create_info.queueCount = 1; + graphic_queue_create_info.pQueuePriorities = queue_priorities; + queue_create_infos.push_back(graphic_queue_create_info); + + VkPhysicalDeviceFeatures device_features = {}; +#if STRICT_REQUIREMENTS + device_features.geometryShader = VK_TRUE; + device_features.dualSrcBlend = VK_TRUE; + device_features.logicOp = VK_TRUE; +#endif + + VkDeviceCreateInfo device_create_info = {}; + device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + device_create_info.queueCreateInfoCount = static_cast(queue_create_infos.size()); + device_create_info.pQueueCreateInfos = queue_create_infos.data(); + /* layers_enabled are the same as instance extensions. + * This is only needed for 1.0 implementations. */ + device_create_info.enabledLayerCount = static_cast(layers_enabled.size()); + device_create_info.ppEnabledLayerNames = layers_enabled.data(); + device_create_info.enabledExtensionCount = static_cast(extensions_device.size()); + device_create_info.ppEnabledExtensionNames = extensions_device.data(); + device_create_info.pEnabledFeatures = &device_features; + + vkCreateDevice(physical_device, &device_create_info, NULL, &device); + } + + void init_generic_queue_family() + { + uint32_t queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, NULL); + + vector queue_families(queue_family_count); + vkGetPhysicalDeviceQueueFamilyProperties( + physical_device, &queue_family_count, queue_families.data()); + + generic_queue_family = 0; + for (const auto &queue_family : queue_families) { + /* Every vulkan implementation by spec must have one queue family that support both graphics + * and compute pipelines. We select this one; compute only queue family hints at async + * compute implementations. */ + if ((queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) && + (queue_family.queueFlags & VK_QUEUE_COMPUTE_BIT)) + { + return; + } + generic_queue_family++; + } + + fprintf(stderr, "Couldn't find any Graphic queue family on selected device\n"); + return; + } +}; + +/** + * A shared device between multiple contexts. + * + * The logical device needs to be shared as multiple contexts can be created and the logical vulkan + * device they share should be the same otherwise memory operations might be done on the incorrect + * device. + */ +static std::optional vulkan_device; + +static GHOST_TSuccess ensure_vulkan_device(VkInstance vk_instance, + VkSurfaceKHR vk_surface, + vector required_extensions) +{ + if (vulkan_device.has_value()) { + return GHOST_kSuccess; + } + + VkPhysicalDevice best_physical_device = VK_NULL_HANDLE; + + uint32_t device_count = 0; + vkEnumeratePhysicalDevices(vk_instance, &device_count, NULL); + + vector physical_devices(device_count); + vkEnumeratePhysicalDevices(vk_instance, &device_count, physical_devices.data()); + + int best_device_score = -1; + for (const auto &physical_device : physical_devices) { + GHOST_DeviceVK device_vk(vk_instance, physical_device); + + if (!device_vk.extensions_support(required_extensions)) { + continue; + } + + if (vk_surface != VK_NULL_HANDLE) { + uint32_t format_count; + vkGetPhysicalDeviceSurfaceFormatsKHR( + device_vk.physical_device, vk_surface, &format_count, NULL); + + uint32_t present_count; + vkGetPhysicalDeviceSurfacePresentModesKHR( + device_vk.physical_device, vk_surface, &present_count, NULL); + + /* For now anything will do. */ + if (format_count == 0 || present_count == 0) { + continue; + } + } + +#if STRICT_REQUIREMENTS + if (!device_vk.features.geometryShader || !device_vk.features.dualSrcBlend || + !device_vk.features.logicOp) + { + continue; + } +#endif + + int device_score = 0; + switch (device_vk.properties.deviceType) { + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + device_score = 400; + break; + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + device_score = 300; + break; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + device_score = 200; + break; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + device_score = 100; + break; + default: + break; + } + if (device_score > best_device_score) { + best_physical_device = physical_device; + best_device_score = device_score; + } + } + + if (best_physical_device == VK_NULL_HANDLE) { + fprintf(stderr, "Error: No suitable Vulkan Device found!\n"); + return GHOST_kFailure; + } + + vulkan_device = std::make_optional(vk_instance, best_physical_device); + + return GHOST_kSuccess; +} + +/** \} */ + GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual, #ifdef _WIN32 HWND hwnd, @@ -155,9 +374,6 @@ GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual, m_context_major_version(contextMajorVersion), m_context_minor_version(contextMinorVersion), m_debug(debug), - m_instance(VK_NULL_HANDLE), - m_physical_device(VK_NULL_HANDLE), - m_device(VK_NULL_HANDLE), m_command_pool(VK_NULL_HANDLE), m_surface(VK_NULL_HANDLE), m_swapchain(VK_NULL_HANDLE), @@ -167,57 +383,56 @@ GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual, GHOST_ContextVK::~GHOST_ContextVK() { - if (m_device) { - vkDeviceWaitIdle(m_device); - } + // TODO: see if we can use a usage counter to free the global device. + if (vulkan_device.has_value()) { + GHOST_DeviceVK &device_vk = *vulkan_device; + device_vk.wait_idle(); - destroySwapchain(); + destroySwapchain(); - if (m_command_pool != VK_NULL_HANDLE) { - vkDestroyCommandPool(m_device, m_command_pool, NULL); - } - if (m_device != VK_NULL_HANDLE) { - vkDestroyDevice(m_device, NULL); - } - if (m_surface != VK_NULL_HANDLE) { - vkDestroySurfaceKHR(m_instance, m_surface, NULL); - } - if (m_instance != VK_NULL_HANDLE) { - vkDestroyInstance(m_instance, NULL); + if (m_command_pool != VK_NULL_HANDLE) { + vkDestroyCommandPool(device_vk.device, m_command_pool, NULL); + } + if (m_surface != VK_NULL_HANDLE) { + vkDestroySurfaceKHR(device_vk.instance, m_surface, NULL); + } + + device_vk.users--; + if (device_vk.users == 0) { + vulkan_device.reset(); + } } } GHOST_TSuccess GHOST_ContextVK::destroySwapchain() { - if (m_device != VK_NULL_HANDLE) { - vkDeviceWaitIdle(m_device); - } - + assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE); m_in_flight_images.resize(0); + VkDevice device = vulkan_device->device; for (auto semaphore : m_image_available_semaphores) { - vkDestroySemaphore(m_device, semaphore, NULL); + vkDestroySemaphore(device, semaphore, NULL); } for (auto semaphore : m_render_finished_semaphores) { - vkDestroySemaphore(m_device, semaphore, NULL); + vkDestroySemaphore(device, semaphore, NULL); } for (auto fence : m_in_flight_fences) { - vkDestroyFence(m_device, fence, NULL); + vkDestroyFence(device, fence, NULL); } for (auto framebuffer : m_swapchain_framebuffers) { - vkDestroyFramebuffer(m_device, framebuffer, NULL); + vkDestroyFramebuffer(device, framebuffer, NULL); } if (m_render_pass != VK_NULL_HANDLE) { - vkDestroyRenderPass(m_device, m_render_pass, NULL); + vkDestroyRenderPass(device, m_render_pass, NULL); } for (auto command_buffer : m_command_buffers) { - vkFreeCommandBuffers(m_device, m_command_pool, 1, &command_buffer); + vkFreeCommandBuffers(device, m_command_pool, 1, &command_buffer); } for (auto imageView : m_swapchain_image_views) { - vkDestroyImageView(m_device, imageView, NULL); + vkDestroyImageView(device, imageView, NULL); } if (m_swapchain != VK_NULL_HANDLE) { - vkDestroySwapchainKHR(m_device, m_swapchain, NULL); + vkDestroySwapchainKHR(device, m_swapchain, NULL); } return GHOST_kSuccess; } @@ -228,9 +443,12 @@ GHOST_TSuccess GHOST_ContextVK::swapBuffers() return GHOST_kFailure; } - vkWaitForFences(m_device, 1, &m_in_flight_fences[m_currentFrame], VK_TRUE, UINT64_MAX); + assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE); + VkDevice device = vulkan_device->device; - VkResult result = vkAcquireNextImageKHR(m_device, + vkWaitForFences(device, 1, &m_in_flight_fences[m_currentFrame], VK_TRUE, UINT64_MAX); + + VkResult result = vkAcquireNextImageKHR(device, m_swapchain, UINT64_MAX, m_image_available_semaphores[m_currentFrame], @@ -252,12 +470,36 @@ GHOST_TSuccess GHOST_ContextVK::swapBuffers() /* Check if a previous frame is using this image (i.e. there is its fence to wait on) */ if (m_in_flight_images[m_currentImage] != VK_NULL_HANDLE) { - vkWaitForFences(m_device, 1, &m_in_flight_images[m_currentImage], VK_TRUE, UINT64_MAX); + vkWaitForFences(device, 1, &m_in_flight_images[m_currentImage], VK_TRUE, UINT64_MAX); } m_in_flight_images[m_currentImage] = m_in_flight_fences[m_currentFrame]; VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT}; + /* Image should be in present src layout before presenting to screen. */ + VkCommandBufferBeginInfo begin_info = {}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + VK_CHECK(vkBeginCommandBuffer(m_command_buffers[m_currentImage], &begin_info)); + VkImageMemoryBarrier barrier{}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + barrier.image = m_swapchain_images[m_currentImage]; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + vkCmdPipelineBarrier(m_command_buffers[m_currentImage], + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_DEPENDENCY_BY_REGION_BIT, + 0, + nullptr, + 0, + nullptr, + 1, + &barrier); + VK_CHECK(vkEndCommandBuffer(m_command_buffers[m_currentImage])); + VkSubmitInfo submit_info = {}; submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.waitSemaphoreCount = 1; @@ -268,11 +510,11 @@ GHOST_TSuccess GHOST_ContextVK::swapBuffers() submit_info.signalSemaphoreCount = 1; submit_info.pSignalSemaphores = &m_render_finished_semaphores[m_currentFrame]; - vkResetFences(m_device, 1, &m_in_flight_fences[m_currentFrame]); + vkResetFences(device, 1, &m_in_flight_fences[m_currentFrame]); VK_CHECK(vkQueueSubmit(m_graphic_queue, 1, &submit_info, m_in_flight_fences[m_currentFrame])); do { - result = vkWaitForFences(m_device, 1, &m_in_flight_fences[m_currentFrame], VK_TRUE, 10000); + result = vkWaitForFences(device, 1, &m_in_flight_fences[m_currentFrame], VK_TRUE, 10000); } while (result == VK_TIMEOUT); VK_CHECK(vkQueueWaitIdle(m_graphic_queue)); @@ -327,10 +569,17 @@ GHOST_TSuccess GHOST_ContextVK::getVulkanHandles(void *r_instance, uint32_t *r_graphic_queue_family, void *r_queue) { - *((VkInstance *)r_instance) = m_instance; - *((VkPhysicalDevice *)r_physical_device) = m_physical_device; - *((VkDevice *)r_device) = m_device; - *r_graphic_queue_family = m_queue_family_graphic; + *((VkInstance *)r_instance) = VK_NULL_HANDLE; + *((VkPhysicalDevice *)r_physical_device) = VK_NULL_HANDLE; + *((VkDevice *)r_device) = VK_NULL_HANDLE; + + if (vulkan_device.has_value()) { + *((VkInstance *)r_instance) = vulkan_device->instance; + *((VkPhysicalDevice *)r_physical_device) = vulkan_device->physical_device; + *((VkDevice *)r_device) = vulkan_device->device; + *r_graphic_queue_family = vulkan_device->generic_queue_family; + } + *((VkQueue *)r_queue) = m_graphic_queue; return GHOST_kSuccess; @@ -454,168 +703,6 @@ static void enableLayer(vector &layers_available, #undef PUSH_VKLAYER } -static bool device_extensions_support(VkPhysicalDevice device, vector required_exts) -{ - uint32_t ext_count; - vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, NULL); - - vector available_exts(ext_count); - vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, available_exts.data()); - - for (const auto &extension_needed : required_exts) { - bool found = false; - for (const auto &extension : available_exts) { - if (strcmp(extension_needed, extension.extensionName) == 0) { - found = true; - break; - } - } - if (!found) { - return false; - } - } - return true; -} - -GHOST_TSuccess GHOST_ContextVK::pickPhysicalDevice(vector required_exts) -{ - m_physical_device = VK_NULL_HANDLE; - - uint32_t device_count = 0; - vkEnumeratePhysicalDevices(m_instance, &device_count, NULL); - - vector physical_devices(device_count); - vkEnumeratePhysicalDevices(m_instance, &device_count, physical_devices.data()); - - int best_device_score = -1; - for (const auto &physical_device : physical_devices) { - VkPhysicalDeviceProperties device_properties; - vkGetPhysicalDeviceProperties(physical_device, &device_properties); - - VkPhysicalDeviceFeatures features; - vkGetPhysicalDeviceFeatures(physical_device, &features); - - DEBUG_PRINTF("%s : \n", device_properties.deviceName); - - if (!device_extensions_support(physical_device, required_exts)) { - DEBUG_PRINTF(" - Device does not support required device extensions.\n"); - continue; - } - - if (m_surface != VK_NULL_HANDLE) { - uint32_t format_count; - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_surface, &format_count, NULL); - - uint32_t present_count; - vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, m_surface, &present_count, NULL); - - /* For now anything will do. */ - if (format_count == 0 || present_count == 0) { - DEBUG_PRINTF(" - Device does not support presentation.\n"); - continue; - } - } - - if (!features.geometryShader) { - /* Needed for wide lines emulation and barycentric coords and a few others. */ - DEBUG_PRINTF(" - Device does not support geometryShader.\n"); - } - if (!features.dualSrcBlend) { - DEBUG_PRINTF(" - Device does not support dualSrcBlend.\n"); - } - if (!features.logicOp) { - /* Needed by UI. */ - DEBUG_PRINTF(" - Device does not support logicOp.\n"); - } - -#if STRICT_REQUIREMENTS - if (!features.geometryShader || !features.dualSrcBlend || !features.logicOp) { - continue; - } -#endif - - int device_score = 0; - switch (device_properties.deviceType) { - case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: - device_score = 400; - break; - case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: - device_score = 300; - break; - case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: - device_score = 200; - break; - case VK_PHYSICAL_DEVICE_TYPE_CPU: - device_score = 100; - break; - default: - break; - } - if (device_score > best_device_score) { - m_physical_device = physical_device; - best_device_score = device_score; - } - DEBUG_PRINTF(" - Device suitable.\n"); - } - - if (m_physical_device == VK_NULL_HANDLE) { - fprintf(stderr, "Error: No suitable Vulkan Device found!\n"); - return GHOST_kFailure; - } - - return GHOST_kSuccess; -} - -static GHOST_TSuccess getGraphicQueueFamily(VkPhysicalDevice device, uint32_t *r_queue_index) -{ - uint32_t queue_family_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, NULL); - - vector queue_families(queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families.data()); - - *r_queue_index = 0; - for (const auto &queue_family : queue_families) { - /* Every vulkan implementation by spec must have one queue family that support both graphics - * and compute pipelines. We select this one; compute only queue family hints at async compute - * implementations. */ - if ((queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) && - (queue_family.queueFlags & VK_QUEUE_COMPUTE_BIT)) - { - return GHOST_kSuccess; - } - (*r_queue_index)++; - } - - fprintf(stderr, "Couldn't find any Graphic queue family on selected device\n"); - return GHOST_kFailure; -} - -static GHOST_TSuccess getPresetQueueFamily(VkPhysicalDevice device, - VkSurfaceKHR surface, - uint32_t *r_queue_index) -{ - uint32_t queue_family_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, NULL); - - vector queue_families(queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families.data()); - - *r_queue_index = 0; - for (int i = 0; i < queue_family_count; i++) { - VkBool32 present_support = false; - vkGetPhysicalDeviceSurfaceSupportKHR(device, *r_queue_index, surface, &present_support); - - if (present_support) { - return GHOST_kSuccess; - } - (*r_queue_index)++; - } - - fprintf(stderr, "Couldn't find any Present queue family on selected device\n"); - return GHOST_kFailure; -} - static GHOST_TSuccess create_render_pass(VkDevice device, VkFormat format, VkRenderPass *r_renderPass) @@ -623,7 +710,7 @@ static GHOST_TSuccess create_render_pass(VkDevice device, VkAttachmentDescription colorAttachment = {}; colorAttachment.format = format; colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; - colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -681,17 +768,19 @@ static GHOST_TSuccess selectPresentMode(VkPhysicalDevice device, GHOST_TSuccess GHOST_ContextVK::createCommandPools() { + assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE); VkCommandPoolCreateInfo poolInfo = {}; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - poolInfo.queueFamilyIndex = m_queue_family_graphic; + poolInfo.queueFamilyIndex = vulkan_device->generic_queue_family; - VK_CHECK(vkCreateCommandPool(m_device, &poolInfo, NULL, &m_command_pool)); + VK_CHECK(vkCreateCommandPool(vulkan_device->device, &poolInfo, NULL, &m_command_pool)); return GHOST_kSuccess; } GHOST_TSuccess GHOST_ContextVK::createGraphicsCommandBuffer() { + assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE); assert(m_command_pool != VK_NULL_HANDLE); assert(m_command_buffers.size() == 0); m_command_buffers.resize(1); @@ -701,12 +790,13 @@ GHOST_TSuccess GHOST_ContextVK::createGraphicsCommandBuffer() alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; alloc_info.commandBufferCount = static_cast(m_command_buffers.size()); - VK_CHECK(vkAllocateCommandBuffers(m_device, &alloc_info, m_command_buffers.data())); + VK_CHECK(vkAllocateCommandBuffers(vulkan_device->device, &alloc_info, m_command_buffers.data())); return GHOST_kSuccess; } GHOST_TSuccess GHOST_ContextVK::createGraphicsCommandBuffers() { + assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE); assert(m_command_pool != VK_NULL_HANDLE); m_command_buffers.resize(m_swapchain_image_views.size()); @@ -716,31 +806,32 @@ GHOST_TSuccess GHOST_ContextVK::createGraphicsCommandBuffers() alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; alloc_info.commandBufferCount = static_cast(m_command_buffers.size()); - VK_CHECK(vkAllocateCommandBuffers(m_device, &alloc_info, m_command_buffers.data())); + VK_CHECK(vkAllocateCommandBuffers(vulkan_device->device, &alloc_info, m_command_buffers.data())); return GHOST_kSuccess; } GHOST_TSuccess GHOST_ContextVK::createSwapchain() { + assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE); m_swapchain_id++; - VkPhysicalDevice device = m_physical_device; + VkPhysicalDevice physical_device = vulkan_device->physical_device; uint32_t format_count; - vkGetPhysicalDeviceSurfaceFormatsKHR(device, m_surface, &format_count, NULL); + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_surface, &format_count, NULL); vector formats(format_count); - vkGetPhysicalDeviceSurfaceFormatsKHR(device, m_surface, &format_count, formats.data()); + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_surface, &format_count, formats.data()); /* TODO choose appropriate format. */ VkSurfaceFormatKHR format = formats[0]; VkPresentModeKHR present_mode; - if (!selectPresentMode(device, m_surface, &present_mode)) { + if (!selectPresentMode(physical_device, m_surface, &present_mode)) { return GHOST_kFailure; } VkSurfaceCapabilitiesKHR capabilities; - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, m_surface, &capabilities); + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, m_surface, &capabilities); m_render_extent = capabilities.currentExtent; if (m_render_extent.width == UINT32_MAX) { @@ -771,34 +862,25 @@ GHOST_TSuccess GHOST_ContextVK::createSwapchain() create_info.imageColorSpace = format.colorSpace; create_info.imageExtent = m_render_extent; create_info.imageArrayLayers = 1; - create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; create_info.preTransform = capabilities.currentTransform; create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; create_info.presentMode = present_mode; create_info.clipped = VK_TRUE; create_info.oldSwapchain = VK_NULL_HANDLE; /* TODO Window resize */ + create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; + create_info.queueFamilyIndexCount = 0; + create_info.pQueueFamilyIndices = NULL; - uint32_t queueFamilyIndices[] = {m_queue_family_graphic, m_queue_family_present}; + VkDevice device = vulkan_device->device; + VK_CHECK(vkCreateSwapchainKHR(device, &create_info, NULL, &m_swapchain)); - if (m_queue_family_graphic != m_queue_family_present) { - create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; - create_info.queueFamilyIndexCount = 2; - create_info.pQueueFamilyIndices = queueFamilyIndices; - } - else { - create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - create_info.queueFamilyIndexCount = 0; - create_info.pQueueFamilyIndices = NULL; - } - - VK_CHECK(vkCreateSwapchainKHR(m_device, &create_info, NULL, &m_swapchain)); - - create_render_pass(m_device, format.format, &m_render_pass); + create_render_pass(device, format.format, &m_render_pass); /* image_count may not be what we requested! Getter for final value. */ - vkGetSwapchainImagesKHR(m_device, m_swapchain, &image_count, NULL); + vkGetSwapchainImagesKHR(device, m_swapchain, &image_count, NULL); m_swapchain_images.resize(image_count); - vkGetSwapchainImagesKHR(m_device, m_swapchain, &image_count, m_swapchain_images.data()); + vkGetSwapchainImagesKHR(device, m_swapchain, &image_count, m_swapchain_images.data()); m_in_flight_images.resize(image_count, VK_NULL_HANDLE); m_swapchain_image_views.resize(image_count); @@ -821,7 +903,7 @@ GHOST_TSuccess GHOST_ContextVK::createSwapchain() view_create_info.subresourceRange.baseArrayLayer = 0; view_create_info.subresourceRange.layerCount = 1; - VK_CHECK(vkCreateImageView(m_device, &view_create_info, NULL, &m_swapchain_image_views[i])); + VK_CHECK(vkCreateImageView(device, &view_create_info, NULL, &m_swapchain_image_views[i])); VkImageView attachments[] = {m_swapchain_image_views[i]}; @@ -834,7 +916,7 @@ GHOST_TSuccess GHOST_ContextVK::createSwapchain() fb_create_info.height = m_render_extent.height; fb_create_info.layers = 1; - VK_CHECK(vkCreateFramebuffer(m_device, &fb_create_info, NULL, &m_swapchain_framebuffers[i])); + VK_CHECK(vkCreateFramebuffer(device, &fb_create_info, NULL, &m_swapchain_framebuffers[i])); } m_image_available_semaphores.resize(MAX_FRAMES_IN_FLIGHT); @@ -845,14 +927,14 @@ GHOST_TSuccess GHOST_ContextVK::createSwapchain() VkSemaphoreCreateInfo semaphore_info = {}; semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - VK_CHECK(vkCreateSemaphore(m_device, &semaphore_info, NULL, &m_image_available_semaphores[i])); - VK_CHECK(vkCreateSemaphore(m_device, &semaphore_info, NULL, &m_render_finished_semaphores[i])); + VK_CHECK(vkCreateSemaphore(device, &semaphore_info, NULL, &m_image_available_semaphores[i])); + VK_CHECK(vkCreateSemaphore(device, &semaphore_info, NULL, &m_render_finished_semaphores[i])); VkFenceCreateInfo fence_info = {}; fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; - VK_CHECK(vkCreateFence(m_device, &fence_info, NULL, &m_in_flight_fences[i])); + VK_CHECK(vkCreateFence(device, &fence_info, NULL, &m_in_flight_fences[i])); } createGraphicsCommandBuffers(); @@ -929,23 +1011,28 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() extensions_available, extensions_enabled, "VK_KHR_get_physical_device_properties2"); #endif - VkApplicationInfo app_info = {}; - app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - app_info.pApplicationName = "Blender"; - app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0); - app_info.pEngineName = "Blender"; - app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0); - app_info.apiVersion = VK_MAKE_VERSION(m_context_major_version, m_context_minor_version, 0); + VkInstance instance = VK_NULL_HANDLE; + if (!vulkan_device.has_value()) { + VkApplicationInfo app_info = {}; + app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + app_info.pApplicationName = "Blender"; + app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + app_info.pEngineName = "Blender"; + app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0); + app_info.apiVersion = VK_MAKE_VERSION(m_context_major_version, m_context_minor_version, 0); - VkInstanceCreateInfo create_info = {}; - create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - create_info.pApplicationInfo = &app_info; - create_info.enabledLayerCount = static_cast(layers_enabled.size()); - create_info.ppEnabledLayerNames = layers_enabled.data(); - create_info.enabledExtensionCount = static_cast(extensions_enabled.size()); - create_info.ppEnabledExtensionNames = extensions_enabled.data(); - - VK_CHECK(vkCreateInstance(&create_info, NULL, &m_instance)); + VkInstanceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + create_info.pApplicationInfo = &app_info; + create_info.enabledLayerCount = static_cast(layers_enabled.size()); + create_info.ppEnabledLayerNames = layers_enabled.data(); + create_info.enabledExtensionCount = static_cast(extensions_enabled.size()); + create_info.ppEnabledExtensionNames = extensions_enabled.data(); + VK_CHECK(vkCreateInstance(&create_info, NULL, &instance)); + } + else { + instance = vulkan_device->instance; + } if (use_window_surface) { #ifdef _WIN32 @@ -953,14 +1040,14 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() surface_create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; surface_create_info.hinstance = GetModuleHandle(NULL); surface_create_info.hwnd = m_hwnd; - VK_CHECK(vkCreateWin32SurfaceKHR(m_instance, &surface_create_info, NULL, &m_surface)); + VK_CHECK(vkCreateWin32SurfaceKHR(instance, &surface_create_info, NULL, &m_surface)); #elif defined(__APPLE__) VkMetalSurfaceCreateInfoEXT info = {}; info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; info.pNext = NULL; info.flags = 0; info.pLayer = m_metal_layer; - VK_CHECK(vkCreateMetalSurfaceEXT(m_instance, &info, nullptr, &m_surface)); + VK_CHECK(vkCreateMetalSurfaceEXT(instance, &info, nullptr, &m_surface)); #else switch (m_platform) { case GHOST_kVulkanPlatformX11: { @@ -968,7 +1055,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() surface_create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; surface_create_info.dpy = m_display; surface_create_info.window = m_window; - VK_CHECK(vkCreateXlibSurfaceKHR(m_instance, &surface_create_info, NULL, &m_surface)); + VK_CHECK(vkCreateXlibSurfaceKHR(instance, &surface_create_info, NULL, &m_surface)); break; } # ifdef WITH_GHOST_WAYLAND @@ -977,7 +1064,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() surface_create_info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; surface_create_info.display = m_wayland_display; surface_create_info.surface = m_wayland_surface; - VK_CHECK(vkCreateWaylandSurfaceKHR(m_instance, &surface_create_info, NULL, &m_surface)); + VK_CHECK(vkCreateWaylandSurfaceKHR(instance, &surface_create_info, NULL, &m_surface)); break; } # endif @@ -986,7 +1073,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() #endif } - if (!pickPhysicalDevice(extensions_device)) { + if (!ensure_vulkan_device(instance, m_surface, extensions_device)) { return GHOST_kFailure; } @@ -994,73 +1081,22 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() /* According to the Vulkan specs, when `VK_KHR_portability_subset` is available it should be * enabled. See * https://vulkan.lunarg.com/doc/view/1.2.198.1/mac/1.2-extensions/vkspec.html#VUID-VkDeviceCreateInfo-pProperties-04451*/ - if (device_extensions_support(m_physical_device, {VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME})) { + if (device_extensions_support(vulkan_device->physical_device, + {VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME})) + { extensions_device.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); } #endif + vulkan_device->users++; + vulkan_device->ensure_device(layers_enabled, extensions_device); - vector queue_create_infos; - - { - /* A graphic queue is required to draw anything. */ - if (!getGraphicQueueFamily(m_physical_device, &m_queue_family_graphic)) { - return GHOST_kFailure; - } - - float queue_priorities[] = {1.0f}; - VkDeviceQueueCreateInfo graphic_queue_create_info = {}; - graphic_queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - graphic_queue_create_info.queueFamilyIndex = m_queue_family_graphic; - graphic_queue_create_info.queueCount = 1; - graphic_queue_create_info.pQueuePriorities = queue_priorities; - queue_create_infos.push_back(graphic_queue_create_info); - } - - if (use_window_surface) { - /* A present queue is required only if we render to a window. */ - if (!getPresetQueueFamily(m_physical_device, m_surface, &m_queue_family_present)) { - return GHOST_kFailure; - } - - float queue_priorities[] = {1.0f}; - VkDeviceQueueCreateInfo present_queue_create_info = {}; - present_queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - present_queue_create_info.queueFamilyIndex = m_queue_family_present; - present_queue_create_info.queueCount = 1; - present_queue_create_info.pQueuePriorities = queue_priorities; - - /* Each queue must be unique. */ - if (m_queue_family_graphic != m_queue_family_present) { - queue_create_infos.push_back(present_queue_create_info); - } - } - - VkPhysicalDeviceFeatures device_features = {}; -#if STRICT_REQUIREMENTS - device_features.geometryShader = VK_TRUE; - device_features.dualSrcBlend = VK_TRUE; - device_features.logicOp = VK_TRUE; -#endif - - VkDeviceCreateInfo device_create_info = {}; - device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - device_create_info.queueCreateInfoCount = static_cast(queue_create_infos.size()); - device_create_info.pQueueCreateInfos = queue_create_infos.data(); - /* layers_enabled are the same as instance extensions. - * This is only needed for 1.0 implementations. */ - device_create_info.enabledLayerCount = static_cast(layers_enabled.size()); - device_create_info.ppEnabledLayerNames = layers_enabled.data(); - device_create_info.enabledExtensionCount = static_cast(extensions_device.size()); - device_create_info.ppEnabledExtensionNames = extensions_device.data(); - device_create_info.pEnabledFeatures = &device_features; - - VK_CHECK(vkCreateDevice(m_physical_device, &device_create_info, NULL, &m_device)); - - vkGetDeviceQueue(m_device, m_queue_family_graphic, 0, &m_graphic_queue); + vkGetDeviceQueue( + vulkan_device->device, vulkan_device->generic_queue_family, 0, &m_graphic_queue); createCommandPools(); if (use_window_surface) { - vkGetDeviceQueue(m_device, m_queue_family_present, 0, &m_present_queue); + vkGetDeviceQueue( + vulkan_device->device, vulkan_device->generic_queue_family, 0, &m_present_queue); createSwapchain(); } else { diff --git a/intern/ghost/intern/GHOST_ContextVK.hh b/intern/ghost/intern/GHOST_ContextVK.hh index aa8af898b1b..8c5d6fe5856 100644 --- a/intern/ghost/intern/GHOST_ContextVK.hh +++ b/intern/ghost/intern/GHOST_ContextVK.hh @@ -164,14 +164,8 @@ class GHOST_ContextVK : public GHOST_Context { const int m_context_minor_version; const int m_debug; - VkInstance m_instance; - VkPhysicalDevice m_physical_device; - VkDevice m_device; VkCommandPool m_command_pool; - uint32_t m_queue_family_graphic; - uint32_t m_queue_family_present; - VkQueue m_graphic_queue; VkQueue m_present_queue; @@ -196,7 +190,6 @@ class GHOST_ContextVK : public GHOST_Context { uint32_t m_swapchain_id = 0; const char *getPlatformSpecificSurfaceExtension() const; - GHOST_TSuccess pickPhysicalDevice(std::vector required_exts); GHOST_TSuccess createSwapchain(); GHOST_TSuccess destroySwapchain(); GHOST_TSuccess createCommandPools(); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index e6c46a23e4e..c2d5daa2201 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -208,6 +208,7 @@ set(VULKAN_SRC vulkan/vk_debug.cc vulkan/vk_descriptor_pools.cc vulkan/vk_descriptor_set.cc + vulkan/vk_device.cc vulkan/vk_drawlist.cc vulkan/vk_fence.cc vulkan/vk_framebuffer.cc @@ -238,6 +239,7 @@ set(VULKAN_SRC vulkan/vk_debug.hh vulkan/vk_descriptor_pools.hh vulkan/vk_descriptor_set.hh + vulkan/vk_device.hh vulkan/vk_drawlist.hh vulkan/vk_fence.hh vulkan/vk_framebuffer.hh diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index a72511b0703..4f3e02fa716 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -52,7 +52,12 @@ void VKBackend::platform_exit() GPG.clear(); } -void VKBackend::delete_resources() {} +void VKBackend::delete_resources() +{ + if (device_.is_initialized()) { + device_.deinit(); + } +} void VKBackend::samplers_update() {} @@ -151,9 +156,10 @@ shaderc::Compiler &VKBackend::get_shaderc_compiler() return shaderc_compiler_; } -void VKBackend::capabilities_init(VKContext &context) +void VKBackend::capabilities_init() { - const VkPhysicalDeviceLimits limits = context.physical_device_limits_get(); + const VkPhysicalDeviceLimits &limits = + VKBackend::get().device_get().physical_device_limits_get(); /* Reset all capabilities from previous context. */ GCaps = {}; diff --git a/source/blender/gpu/vulkan/vk_backend.hh b/source/blender/gpu/vulkan/vk_backend.hh index e15e69a4234..65599f9dfe3 100644 --- a/source/blender/gpu/vulkan/vk_backend.hh +++ b/source/blender/gpu/vulkan/vk_backend.hh @@ -14,12 +14,15 @@ #endif #include "vk_common.hh" +#include "vk_device.hh" #include "shaderc/shaderc.hpp" namespace blender::gpu { class VKContext; +class VKDescriptorSet; +class VKDescriptorSetTracker; class VKBackend : public GPUBackend { private: @@ -27,6 +30,8 @@ class VKBackend : public GPUBackend { #ifdef WITH_RENDERDOC renderdoc::api::Renderdoc renderdoc_api_; #endif + /* Global instance to device handles. */ + VKDevice device_; public: VKBackend() @@ -66,21 +71,31 @@ class VKBackend : public GPUBackend { void render_end() override; void render_step() override; - bool debug_capture_begin(VkInstance vk_instance); - void debug_capture_end(VkInstance vk_instance); + bool debug_capture_begin(); + void debug_capture_end(); shaderc::Compiler &get_shaderc_compiler(); - static void capabilities_init(VKContext &context); + static void capabilities_init(); static VKBackend &get() { return *static_cast(GPUBackend::get()); } + const VKDevice &device_get() const + { + return device_; + } + private: static void init_platform(); static void platform_exit(); + + /* These classes are allowed to modify the global device. */ + friend class VKContext; + friend class VKDescriptorSet; + friend class VKDescriptorSetTracker; }; } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_buffer.cc b/source/blender/gpu/vulkan/vk_buffer.cc index 98ccefacc97..fe19f270d11 100644 --- a/source/blender/gpu/vulkan/vk_buffer.cc +++ b/source/blender/gpu/vulkan/vk_buffer.cc @@ -6,14 +6,14 @@ */ #include "vk_buffer.hh" +#include "vk_backend.hh" #include "vk_context.hh" namespace blender::gpu { VKBuffer::~VKBuffer() { - VKContext &context = *VKContext::get(); - free(context); + free(); } bool VKBuffer::is_allocated() const @@ -41,16 +41,16 @@ static VmaAllocationCreateFlagBits vma_allocation_flags(GPUUsageType usage) VMA_ALLOCATION_CREATE_MAPPED_BIT); } -bool VKBuffer::create(VKContext &context, - int64_t size_in_bytes, +bool VKBuffer::create(int64_t size_in_bytes, GPUUsageType usage, VkBufferUsageFlagBits buffer_usage) { BLI_assert(!is_allocated()); size_in_bytes_ = size_in_bytes; + const VKDevice &device = VKBackend::get().device_get(); - VmaAllocator allocator = context.mem_allocator_get(); + VmaAllocator allocator = device.mem_allocator_get(); VkBufferCreateInfo create_info = {}; create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; create_info.flags = 0; @@ -60,7 +60,7 @@ bool VKBuffer::create(VKContext &context, * exclusive resource handling. */ create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; create_info.queueFamilyIndexCount = 1; - create_info.pQueueFamilyIndices = context.queue_family_ptr_get(); + create_info.pQueueFamilyIndices = device.queue_family_ptr_get(); VmaAllocationCreateInfo vma_create_info = {}; vma_create_info.flags = vma_allocation_flags(usage); @@ -74,7 +74,7 @@ bool VKBuffer::create(VKContext &context, } /* All buffers are mapped to virtual memory. */ - return map(context); + return map(); } void VKBuffer::update(const void *data) const @@ -82,9 +82,9 @@ void VKBuffer::update(const void *data) const BLI_assert_msg(is_mapped(), "Cannot update a non-mapped buffer."); memcpy(mapped_memory_, data, size_in_bytes_); - VKContext &context = *VKContext::get(); - VmaAllocator mem_allocator = context.mem_allocator_get(); - vmaFlushAllocation(mem_allocator, allocation_, 0, VK_WHOLE_SIZE); + const VKDevice &device = VKBackend::get().device_get(); + VmaAllocator allocator = device.mem_allocator_get(); + vmaFlushAllocation(allocator, allocation_, 0, VK_WHOLE_SIZE); } void VKBuffer::clear(VKContext &context, uint32_t clear_value) @@ -110,29 +110,32 @@ bool VKBuffer::is_mapped() const return mapped_memory_ != nullptr; } -bool VKBuffer::map(VKContext &context) +bool VKBuffer::map() { BLI_assert(!is_mapped()); - VmaAllocator allocator = context.mem_allocator_get(); + const VKDevice &device = VKBackend::get().device_get(); + VmaAllocator allocator = device.mem_allocator_get(); VkResult result = vmaMapMemory(allocator, allocation_, &mapped_memory_); return result == VK_SUCCESS; } -void VKBuffer::unmap(VKContext &context) +void VKBuffer::unmap() { BLI_assert(is_mapped()); - VmaAllocator allocator = context.mem_allocator_get(); + const VKDevice &device = VKBackend::get().device_get(); + VmaAllocator allocator = device.mem_allocator_get(); vmaUnmapMemory(allocator, allocation_); mapped_memory_ = nullptr; } -bool VKBuffer::free(VKContext &context) +bool VKBuffer::free() { if (is_mapped()) { - unmap(context); + unmap(); } - VmaAllocator allocator = context.mem_allocator_get(); + const VKDevice &device = VKBackend::get().device_get(); + VmaAllocator allocator = device.mem_allocator_get(); vmaDestroyBuffer(allocator, vk_buffer_, allocation_); return true; } diff --git a/source/blender/gpu/vulkan/vk_buffer.hh b/source/blender/gpu/vulkan/vk_buffer.hh index 17afba6c4ac..3fa263f1e8a 100644 --- a/source/blender/gpu/vulkan/vk_buffer.hh +++ b/source/blender/gpu/vulkan/vk_buffer.hh @@ -31,14 +31,11 @@ class VKBuffer { /** Has this buffer been allocated? */ bool is_allocated() const; - bool create(VKContext &context, - int64_t size, - GPUUsageType usage, - VkBufferUsageFlagBits buffer_usage); + bool create(int64_t size, GPUUsageType usage, VkBufferUsageFlagBits buffer_usage); void clear(VKContext &context, uint32_t clear_value); void update(const void *data) const; void read(void *data) const; - bool free(VKContext &context); + bool free(); int64_t size_in_bytes() const { @@ -60,8 +57,8 @@ class VKBuffer { private: /** Check if this buffer is mapped. */ bool is_mapped() const; - bool map(VKContext &context); - void unmap(VKContext &context); + bool map(); + void unmap(); }; } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index c2d8890eef2..f4d15d2078c 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -18,56 +18,23 @@ namespace blender::gpu { VKContext::VKContext(void *ghost_window, void *ghost_context) { - VK_ALLOCATION_CALLBACKS; ghost_window_ = ghost_window; if (ghost_window) { ghost_context = GHOST_GetDrawingContext((GHOST_WindowHandle)ghost_window); } ghost_context_ = ghost_context; - - GHOST_GetVulkanHandles((GHOST_ContextHandle)ghost_context, - &vk_instance_, - &vk_physical_device_, - &vk_device_, - &vk_queue_family_, - &vk_queue_); - debug::init_callbacks(this, vkGetInstanceProcAddr); - init_physical_device_limits(); - - debug::object_label(this, vk_device_, "LogicalDevice"); - debug::object_label(this, vk_queue_, "GenericQueue"); - - /* Initialize the memory allocator. */ - VmaAllocatorCreateInfo info = {}; - info.vulkanApiVersion = VK_API_VERSION_1_2; - info.physicalDevice = vk_physical_device_; - info.device = vk_device_; - info.instance = vk_instance_; - info.pAllocationCallbacks = vk_allocation_callbacks; - vmaCreateAllocator(&info, &mem_allocator_); - descriptor_pools_.init(vk_device_); + VKDevice &device = VKBackend::get().device_; + if (!device.is_initialized()) { + device.init(ghost_context); + } state_manager = new VKStateManager(); - VKBackend::capabilities_init(*this); - /* For off-screen contexts. Default frame-buffer is empty. */ back_left = new VKFrameBuffer("back_left"); } -VKContext::~VKContext() -{ - vmaDestroyAllocator(mem_allocator_); - debug::destroy_callbacks(this); -} - -void VKContext::init_physical_device_limits() -{ - BLI_assert(vk_physical_device_ != VK_NULL_HANDLE); - VkPhysicalDeviceProperties properties = {}; - vkGetPhysicalDeviceProperties(vk_physical_device_, &properties); - vk_physical_device_limits_ = properties.limits; -} +VKContext::~VKContext() {} void VKContext::activate() { @@ -100,10 +67,10 @@ void VKContext::begin_frame() { VkCommandBuffer command_buffer = VK_NULL_HANDLE; GHOST_GetVulkanCommandBuffer(static_cast(ghost_context_), &command_buffer); - command_buffer_.init(vk_device_, vk_queue_, command_buffer); + VKDevice &device = VKBackend::get().device_; + command_buffer_.init(device.device_get(), device.queue_get(), command_buffer); command_buffer_.begin_recording(); - - descriptor_pools_.reset(); + device.descriptor_pools_get().reset(); } void VKContext::end_frame() diff --git a/source/blender/gpu/vulkan/vk_context.hh b/source/blender/gpu/vulkan/vk_context.hh index 35980051386..5088b1db522 100644 --- a/source/blender/gpu/vulkan/vk_context.hh +++ b/source/blender/gpu/vulkan/vk_context.hh @@ -19,23 +19,7 @@ class VKStateManager; class VKContext : public Context, NonCopyable { private: - /** Copies of the handles owned by the GHOST context. */ - VkInstance vk_instance_ = VK_NULL_HANDLE; - VkPhysicalDevice vk_physical_device_ = VK_NULL_HANDLE; - VkDevice vk_device_ = VK_NULL_HANDLE; VKCommandBuffer command_buffer_; - uint32_t vk_queue_family_ = 0; - VkQueue vk_queue_ = VK_NULL_HANDLE; - - /** Allocator used for texture and buffers and other resources. */ - VmaAllocator mem_allocator_ = VK_NULL_HANDLE; - VKDescriptorPools descriptor_pools_; - - /** Limits of the device linked to this context. */ - VkPhysicalDeviceLimits vk_physical_device_limits_; - - /** Functions of vk_ext_debugutils to use in this context. */ - debug::VKDebuggingTools debugging_tools_; void *ghost_context_; @@ -69,66 +53,15 @@ class VKContext : public Context, NonCopyable { return static_cast(Context::get()); } - VkPhysicalDevice physical_device_get() const - { - return vk_physical_device_; - } - - const VkPhysicalDeviceLimits &physical_device_limits_get() const - { - return vk_physical_device_limits_; - } - - VkInstance instance_get() const - { - return vk_instance_; - }; - - VkDevice device_get() const - { - return vk_device_; - } - VKCommandBuffer &command_buffer_get() { return command_buffer_; } - VkQueue queue_get() const - { - return vk_queue_; - } - - const uint32_t *queue_family_ptr_get() const - { - return &vk_queue_family_; - } - - VKDescriptorPools &descriptor_pools_get() - { - return descriptor_pools_; - } - const VKStateManager &state_manager_get() const; - VmaAllocator mem_allocator_get() const - { - return mem_allocator_; - } - - debug::VKDebuggingTools &debugging_tools_get() - { - return debugging_tools_; - } - - const debug::VKDebuggingTools &debugging_tools_get() const - { - return debugging_tools_; - } private: - void init_physical_device_limits(); - bool has_active_framebuffer() const; }; diff --git a/source/blender/gpu/vulkan/vk_debug.cc b/source/blender/gpu/vulkan/vk_debug.cc index 9af2cdccb00..3a3d505ed35 100644 --- a/source/blender/gpu/vulkan/vk_debug.cc +++ b/source/blender/gpu/vulkan/vk_debug.cc @@ -14,40 +14,39 @@ namespace blender::gpu { void VKContext::debug_group_begin(const char *name, int) { - debug::push_marker(this, vk_queue_, name); + const VKDevice &device = VKBackend::get().device_get(); + debug::push_marker(device, name); } void VKContext::debug_group_end() { - debug::pop_marker(this, vk_queue_); + const VKDevice &device = VKBackend::get().device_get(); + debug::pop_marker(device); } bool VKContext::debug_capture_begin() { - return VKBackend::get().debug_capture_begin(vk_instance_); + return VKBackend::get().debug_capture_begin(); } -bool VKBackend::debug_capture_begin(VkInstance vk_instance) +bool VKBackend::debug_capture_begin() { #ifdef WITH_RENDERDOC - return renderdoc_api_.start_frame_capture(vk_instance, nullptr); + return renderdoc_api_.start_frame_capture(device_get().instance_get(), nullptr); #else - UNUSED_VARS(vk_instance); return false; #endif } void VKContext::debug_capture_end() { - VKBackend::get().debug_capture_end(vk_instance_); + VKBackend::get().debug_capture_end(); } -void VKBackend::debug_capture_end(VkInstance vk_instance) +void VKBackend::debug_capture_end() { #ifdef WITH_RENDERDOC - renderdoc_api_.end_frame_capture(vk_instance, nullptr); -#else - UNUSED_VARS(vk_instance); + renderdoc_api_.end_frame_capture(device_get().instance_get(), nullptr); #endif } @@ -66,96 +65,74 @@ void VKContext::debug_capture_scope_end(void * /*scope*/) {} namespace blender::gpu::debug { -static void load_dynamic_functions(VKContext *context, - PFN_vkGetInstanceProcAddr instance_proc_addr) +void VKDebuggingTools::init(VkInstance vk_instance) { - VKDebuggingTools &debugging_tools = context->debugging_tools_get(); - VkInstance vk_instance = context->instance_get(); - - if (instance_proc_addr) { - - debugging_tools.enabled = false; - debugging_tools.vkCmdBeginDebugUtilsLabelEXT_r = (PFN_vkCmdBeginDebugUtilsLabelEXT) - instance_proc_addr(vk_instance, "vkCmdBeginDebugUtilsLabelEXT"); - debugging_tools.vkCmdEndDebugUtilsLabelEXT_r = (PFN_vkCmdEndDebugUtilsLabelEXT) - instance_proc_addr(vk_instance, "vkCmdEndDebugUtilsLabelEXT"); - debugging_tools.vkCmdInsertDebugUtilsLabelEXT_r = (PFN_vkCmdInsertDebugUtilsLabelEXT) - instance_proc_addr(vk_instance, "vkCmdInsertDebugUtilsLabelEXT"); - debugging_tools.vkCreateDebugUtilsMessengerEXT_r = (PFN_vkCreateDebugUtilsMessengerEXT) - instance_proc_addr(vk_instance, "vkCreateDebugUtilsMessengerEXT"); - debugging_tools.vkDestroyDebugUtilsMessengerEXT_r = (PFN_vkDestroyDebugUtilsMessengerEXT) - instance_proc_addr(vk_instance, "vkDestroyDebugUtilsMessengerEXT"); - debugging_tools.vkQueueBeginDebugUtilsLabelEXT_r = (PFN_vkQueueBeginDebugUtilsLabelEXT) - instance_proc_addr(vk_instance, "vkQueueBeginDebugUtilsLabelEXT"); - debugging_tools.vkQueueEndDebugUtilsLabelEXT_r = (PFN_vkQueueEndDebugUtilsLabelEXT) - instance_proc_addr(vk_instance, "vkQueueEndDebugUtilsLabelEXT"); - debugging_tools.vkQueueInsertDebugUtilsLabelEXT_r = (PFN_vkQueueInsertDebugUtilsLabelEXT) - instance_proc_addr(vk_instance, "vkQueueInsertDebugUtilsLabelEXT"); - debugging_tools.vkSetDebugUtilsObjectNameEXT_r = (PFN_vkSetDebugUtilsObjectNameEXT) - instance_proc_addr(vk_instance, "vkSetDebugUtilsObjectNameEXT"); - debugging_tools.vkSetDebugUtilsObjectTagEXT_r = (PFN_vkSetDebugUtilsObjectTagEXT) - instance_proc_addr(vk_instance, "vkSetDebugUtilsObjectTagEXT"); - debugging_tools.vkSubmitDebugUtilsMessageEXT_r = (PFN_vkSubmitDebugUtilsMessageEXT) - instance_proc_addr(vk_instance, "vkSubmitDebugUtilsMessageEXT"); - if (debugging_tools.vkCmdBeginDebugUtilsLabelEXT_r) { - debugging_tools.enabled = true; - } - } - else { - debugging_tools.vkCmdBeginDebugUtilsLabelEXT_r = nullptr; - debugging_tools.vkCmdEndDebugUtilsLabelEXT_r = nullptr; - debugging_tools.vkCmdInsertDebugUtilsLabelEXT_r = nullptr; - debugging_tools.vkCreateDebugUtilsMessengerEXT_r = nullptr; - debugging_tools.vkDestroyDebugUtilsMessengerEXT_r = nullptr; - debugging_tools.vkQueueBeginDebugUtilsLabelEXT_r = nullptr; - debugging_tools.vkQueueEndDebugUtilsLabelEXT_r = nullptr; - debugging_tools.vkQueueInsertDebugUtilsLabelEXT_r = nullptr; - debugging_tools.vkSetDebugUtilsObjectNameEXT_r = nullptr; - debugging_tools.vkSetDebugUtilsObjectTagEXT_r = nullptr; - debugging_tools.vkSubmitDebugUtilsMessageEXT_r = nullptr; - debugging_tools.enabled = false; + PFN_vkGetInstanceProcAddr instance_proc_addr = vkGetInstanceProcAddr; + enabled = false; + vkCmdBeginDebugUtilsLabelEXT_r = (PFN_vkCmdBeginDebugUtilsLabelEXT)instance_proc_addr( + vk_instance, "vkCmdBeginDebugUtilsLabelEXT"); + vkCmdEndDebugUtilsLabelEXT_r = (PFN_vkCmdEndDebugUtilsLabelEXT)instance_proc_addr( + vk_instance, "vkCmdEndDebugUtilsLabelEXT"); + vkCmdInsertDebugUtilsLabelEXT_r = (PFN_vkCmdInsertDebugUtilsLabelEXT)instance_proc_addr( + vk_instance, "vkCmdInsertDebugUtilsLabelEXT"); + vkCreateDebugUtilsMessengerEXT_r = (PFN_vkCreateDebugUtilsMessengerEXT)instance_proc_addr( + vk_instance, "vkCreateDebugUtilsMessengerEXT"); + vkDestroyDebugUtilsMessengerEXT_r = (PFN_vkDestroyDebugUtilsMessengerEXT)instance_proc_addr( + vk_instance, "vkDestroyDebugUtilsMessengerEXT"); + vkQueueBeginDebugUtilsLabelEXT_r = (PFN_vkQueueBeginDebugUtilsLabelEXT)instance_proc_addr( + vk_instance, "vkQueueBeginDebugUtilsLabelEXT"); + vkQueueEndDebugUtilsLabelEXT_r = (PFN_vkQueueEndDebugUtilsLabelEXT)instance_proc_addr( + vk_instance, "vkQueueEndDebugUtilsLabelEXT"); + vkQueueInsertDebugUtilsLabelEXT_r = (PFN_vkQueueInsertDebugUtilsLabelEXT)instance_proc_addr( + vk_instance, "vkQueueInsertDebugUtilsLabelEXT"); + vkSetDebugUtilsObjectNameEXT_r = (PFN_vkSetDebugUtilsObjectNameEXT)instance_proc_addr( + vk_instance, "vkSetDebugUtilsObjectNameEXT"); + vkSetDebugUtilsObjectTagEXT_r = (PFN_vkSetDebugUtilsObjectTagEXT)instance_proc_addr( + vk_instance, "vkSetDebugUtilsObjectTagEXT"); + vkSubmitDebugUtilsMessageEXT_r = (PFN_vkSubmitDebugUtilsMessageEXT)instance_proc_addr( + vk_instance, "vkSubmitDebugUtilsMessageEXT"); + if (vkCmdBeginDebugUtilsLabelEXT_r) { + enabled = true; } } -bool init_callbacks(VKContext *context, PFN_vkGetInstanceProcAddr instance_proc_addr) +void VKDebuggingTools::deinit() { - if (instance_proc_addr) { - load_dynamic_functions(context, instance_proc_addr); - return true; - }; - return false; + vkCmdBeginDebugUtilsLabelEXT_r = nullptr; + vkCmdEndDebugUtilsLabelEXT_r = nullptr; + vkCmdInsertDebugUtilsLabelEXT_r = nullptr; + vkCreateDebugUtilsMessengerEXT_r = nullptr; + vkDestroyDebugUtilsMessengerEXT_r = nullptr; + vkQueueBeginDebugUtilsLabelEXT_r = nullptr; + vkQueueEndDebugUtilsLabelEXT_r = nullptr; + vkQueueInsertDebugUtilsLabelEXT_r = nullptr; + vkSetDebugUtilsObjectNameEXT_r = nullptr; + vkSetDebugUtilsObjectTagEXT_r = nullptr; + vkSubmitDebugUtilsMessageEXT_r = nullptr; + enabled = false; } -void destroy_callbacks(VKContext *context) -{ - VKDebuggingTools &debugging_tools = context->debugging_tools_get(); - if (debugging_tools.enabled) { - load_dynamic_functions(context, nullptr); - } -} - -void object_label(VKContext *context, - VkObjectType vk_object_type, - uint64_t object_handle, - const char *name) +void object_label(VkObjectType vk_object_type, uint64_t object_handle, const char *name) { if (G.debug & G_DEBUG_GPU) { - const VKDebuggingTools &debugging_tools = context->debugging_tools_get(); + const VKDevice &device = VKBackend::get().device_get(); + const VKDebuggingTools &debugging_tools = device.debugging_tools_get(); if (debugging_tools.enabled) { VkDebugUtilsObjectNameInfoEXT info = {}; info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; info.objectType = vk_object_type; info.objectHandle = object_handle; info.pObjectName = name; - debugging_tools.vkSetDebugUtilsObjectNameEXT_r(context->device_get(), &info); + debugging_tools.vkSetDebugUtilsObjectNameEXT_r(device.device_get(), &info); } } } -void push_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const char *name) +void push_marker(VkCommandBuffer vk_command_buffer, const char *name) { if (G.debug & G_DEBUG_GPU) { - const VKDebuggingTools &debugging_tools = context->debugging_tools_get(); + const VKDevice &device = VKBackend::get().device_get(); + const VKDebuggingTools &debugging_tools = device.debugging_tools_get(); if (debugging_tools.enabled) { VkDebugUtilsLabelEXT info = {}; info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; @@ -165,10 +142,11 @@ void push_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const ch } } -void set_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const char *name) +void set_marker(VkCommandBuffer vk_command_buffer, const char *name) { if (G.debug & G_DEBUG_GPU) { - const VKDebuggingTools &debugging_tools = context->debugging_tools_get(); + const VKDevice &device = VKBackend::get().device_get(); + const VKDebuggingTools &debugging_tools = device.debugging_tools_get(); if (debugging_tools.enabled) { VkDebugUtilsLabelEXT info = {}; info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; @@ -178,49 +156,51 @@ void set_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const cha } } -void pop_marker(VKContext *context, VkCommandBuffer vk_command_buffer) +void pop_marker(VkCommandBuffer vk_command_buffer) { if (G.debug & G_DEBUG_GPU) { - const VKDebuggingTools &debugging_tools = context->debugging_tools_get(); + const VKDevice &device = VKBackend::get().device_get(); + const VKDebuggingTools &debugging_tools = device.debugging_tools_get(); if (debugging_tools.enabled) { debugging_tools.vkCmdEndDebugUtilsLabelEXT_r(vk_command_buffer); } } } -void push_marker(VKContext *context, VkQueue vk_queue, const char *name) +void push_marker(const VKDevice &device, const char *name) { if (G.debug & G_DEBUG_GPU) { - const VKDebuggingTools &debugging_tools = context->debugging_tools_get(); + const VKDebuggingTools &debugging_tools = device.debugging_tools_get(); if (debugging_tools.enabled) { VkDebugUtilsLabelEXT info = {}; info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; info.pLabelName = name; - debugging_tools.vkQueueBeginDebugUtilsLabelEXT_r(vk_queue, &info); + debugging_tools.vkQueueBeginDebugUtilsLabelEXT_r(device.queue_get(), &info); } } } -void set_marker(VKContext *context, VkQueue vk_queue, const char *name) +void set_marker(const VKDevice &device, const char *name) { if (G.debug & G_DEBUG_GPU) { - const VKDebuggingTools &debugging_tools = context->debugging_tools_get(); + const VKDebuggingTools &debugging_tools = device.debugging_tools_get(); if (debugging_tools.enabled) { VkDebugUtilsLabelEXT info = {}; info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; info.pLabelName = name; - debugging_tools.vkQueueInsertDebugUtilsLabelEXT_r(vk_queue, &info); + debugging_tools.vkQueueInsertDebugUtilsLabelEXT_r(device.queue_get(), &info); } } } -void pop_marker(VKContext *context, VkQueue vk_queue) +void pop_marker(const VKDevice &device) { if (G.debug & G_DEBUG_GPU) { - const VKDebuggingTools &debugging_tools = context->debugging_tools_get(); + const VKDebuggingTools &debugging_tools = device.debugging_tools_get(); if (debugging_tools.enabled) { - debugging_tools.vkQueueEndDebugUtilsLabelEXT_r(vk_queue); + debugging_tools.vkQueueEndDebugUtilsLabelEXT_r(device.queue_get()); } } } + } // namespace blender::gpu::debug diff --git a/source/blender/gpu/vulkan/vk_debug.hh b/source/blender/gpu/vulkan/vk_debug.hh index 6123ab7d704..7fe77338c81 100644 --- a/source/blender/gpu/vulkan/vk_debug.hh +++ b/source/blender/gpu/vulkan/vk_debug.hh @@ -15,8 +15,10 @@ namespace blender::gpu { class VKContext; +class VKDevice; + namespace debug { -typedef struct VKDebuggingTools { +struct VKDebuggingTools { bool enabled = false; /* Function pointer definitions. */ PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT_r = nullptr; @@ -31,16 +33,12 @@ typedef struct VKDebuggingTools { PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT_r = nullptr; PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT_r = nullptr; -} VKDebuggingTools; + void init(VkInstance vk_instance); + void deinit(); +}; -bool init_callbacks(VKContext *context, PFN_vkGetInstanceProcAddr instance_proc_addr); -void destroy_callbacks(VKContext *context); -void object_label(VKContext *context, - VkObjectType vk_object_type, - uint64_t object_handle, - const char *name); - -template void object_label(VKContext *context, T vk_object_type, const char *name) +void object_label(VkObjectType vk_object_type, uint64_t object_handle, const char *name); +template void object_label(T vk_object_type, const char *name) { if (!(G.debug & G_DEBUG_GPU)) { return; @@ -50,15 +48,14 @@ template void object_label(VKContext *context, T vk_object_type, con memset(label, 0, label_size); static int stats = 0; SNPRINTF(label, "%s_%d", name, stats++); - object_label( - context, to_vk_object_type(vk_object_type), (uint64_t)vk_object_type, (const char *)label); + object_label(to_vk_object_type(vk_object_type), (uint64_t)vk_object_type, (const char *)label); }; -void push_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const char *name); -void set_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const char *name); -void pop_marker(VKContext *context, VkCommandBuffer vk_command_buffer); -void push_marker(VKContext *context, VkQueue vk_queue, const char *name); -void set_marker(VKContext *context, VkQueue vk_queue, const char *name); -void pop_marker(VKContext *context, VkQueue vk_queue); +void push_marker(VkCommandBuffer vk_command_buffer, const char *name); +void set_marker(VkCommandBuffer vk_command_buffer, const char *name); +void pop_marker(VkCommandBuffer vk_command_buffer); +void push_marker(const VKDevice &device, const char *name); +void set_marker(const VKDevice &device, const char *name); +void pop_marker(const VKDevice &device); } // namespace debug } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index 3a72c419ae6..edf6d7b54a7 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -27,8 +27,9 @@ VKDescriptorSet::~VKDescriptorSet() { if (vk_descriptor_set_ != VK_NULL_HANDLE) { /* Handle should be given back to the pool. */ - VKContext &context = *VKContext::get(); - context.descriptor_pools_get().free(*this); + BLI_assert(VKContext::get()); + VKDevice &device = VKBackend::get().device_; + device.descriptor_pools_get().free(*this); BLI_assert(vk_descriptor_set_ == VK_NULL_HANDLE); } } @@ -150,16 +151,17 @@ void VKDescriptorSetTracker::update(VKContext &context) "Not all changes have been converted to a write descriptor. Check " "`Binding::is_buffer` and `Binding::is_image`."); - VkDevice vk_device = context.device_get(); + const VKDevice &device = VKBackend::get().device_get(); vkUpdateDescriptorSets( - vk_device, descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); + device.device_get(), descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); bindings_.clear(); } std::unique_ptr VKDescriptorSetTracker::create_resource(VKContext &context) { - return context.descriptor_pools_get().allocate(layout_); + VKDevice &device = VKBackend::get().device_; + return device.descriptor_pools_get().allocate(layout_); } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc new file mode 100644 index 00000000000..c396f277419 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation */ + +/** \file + * \ingroup gpu + */ + +#include "vk_device.hh" +#include "vk_backend.hh" +#include "vk_memory.hh" + +#include "GHOST_C-api.h" + +namespace blender::gpu { + +void VKDevice::deinit() +{ + vmaDestroyAllocator(mem_allocator_); + mem_allocator_ = VK_NULL_HANDLE; + debugging_tools_.deinit(); + + vk_instance_ = VK_NULL_HANDLE; + vk_physical_device_ = VK_NULL_HANDLE; + vk_device_ = VK_NULL_HANDLE; + vk_queue_family_ = 0; + vk_queue_ = VK_NULL_HANDLE; + vk_physical_device_limits_ = {}; +} + +bool VKDevice::is_initialized() const +{ + return vk_device_ != VK_NULL_HANDLE; +} + +void VKDevice::init(void *ghost_context) +{ + BLI_assert(!is_initialized()); + GHOST_GetVulkanHandles((GHOST_ContextHandle)ghost_context, + &vk_instance_, + &vk_physical_device_, + &vk_device_, + &vk_queue_family_, + &vk_queue_); + + init_physical_device_limits(); + init_capabilities(); + init_debug_callbacks(); + init_memory_allocator(); + init_descriptor_pools(); + + debug::object_label(device_get(), "LogicalDevice"); + debug::object_label(queue_get(), "GenericQueue"); +} + +void VKDevice::init_debug_callbacks() +{ + debugging_tools_.init(vk_instance_); +} + +void VKDevice::init_physical_device_limits() +{ + BLI_assert(vk_physical_device_ != VK_NULL_HANDLE); + VkPhysicalDeviceProperties properties = {}; + vkGetPhysicalDeviceProperties(vk_physical_device_, &properties); + vk_physical_device_limits_ = properties.limits; +} + +void VKDevice::init_capabilities() +{ + VKBackend::capabilities_init(); +} + +void VKDevice::init_memory_allocator() +{ + VK_ALLOCATION_CALLBACKS; + VmaAllocatorCreateInfo info = {}; + info.vulkanApiVersion = VK_API_VERSION_1_2; + info.physicalDevice = vk_physical_device_; + info.device = vk_device_; + info.instance = vk_instance_; + info.pAllocationCallbacks = vk_allocation_callbacks; + vmaCreateAllocator(&info, &mem_allocator_); +} + +void VKDevice::init_descriptor_pools() +{ + descriptor_pools_.init(vk_device_); +} + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh new file mode 100644 index 00000000000..c0df1ec703f --- /dev/null +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "BLI_utility_mixins.hh" + +#include "vk_common.hh" +#include "vk_debug.hh" +#include "vk_descriptor_pools.hh" + +namespace blender::gpu { + +class VKDevice : public NonCopyable { + private: + /** Copies of the handles owned by the GHOST context. */ + VkInstance vk_instance_ = VK_NULL_HANDLE; + VkPhysicalDevice vk_physical_device_ = VK_NULL_HANDLE; + VkDevice vk_device_ = VK_NULL_HANDLE; + uint32_t vk_queue_family_ = 0; + VkQueue vk_queue_ = VK_NULL_HANDLE; + + /** Allocator used for texture and buffers and other resources. */ + VmaAllocator mem_allocator_ = VK_NULL_HANDLE; + VKDescriptorPools descriptor_pools_; + + /** Limits of the device linked to this context. */ + VkPhysicalDeviceLimits vk_physical_device_limits_; + + /** Functions of vk_ext_debugutils for this device/instance. */ + debug::VKDebuggingTools debugging_tools_; + + public: + VkPhysicalDevice physical_device_get() const + { + return vk_physical_device_; + } + + const VkPhysicalDeviceLimits &physical_device_limits_get() const + { + return vk_physical_device_limits_; + } + + VkInstance instance_get() const + { + return vk_instance_; + }; + + VkDevice device_get() const + { + return vk_device_; + } + + VkQueue queue_get() const + { + return vk_queue_; + } + + VKDescriptorPools &descriptor_pools_get() + { + return descriptor_pools_; + } + + const uint32_t *queue_family_ptr_get() const + { + return &vk_queue_family_; + } + + VmaAllocator mem_allocator_get() const + { + return mem_allocator_; + } + + debug::VKDebuggingTools &debugging_tools_get() + { + return debugging_tools_; + } + + const debug::VKDebuggingTools &debugging_tools_get() const + { + return debugging_tools_; + } + + bool is_initialized() const; + void init(void *ghost_context); + void deinit(); + + private: + void init_physical_device_limits(); + void init_capabilities(); + void init_debug_callbacks(); + void init_memory_allocator(); + void init_descriptor_pools(); +}; + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index 1fdb85a3a39..666427098e3 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -6,6 +6,7 @@ */ #include "vk_framebuffer.hh" +#include "vk_backend.hh" #include "vk_memory.hh" #include "vk_texture.hh" @@ -344,9 +345,9 @@ void VKFrameBuffer::render_pass_create() render_pass_info.subpassCount = 1; render_pass_info.pSubpasses = &subpass; - VKContext &context = *VKContext::get(); + const VKDevice &device = VKBackend::get().device_get(); vkCreateRenderPass( - context.device_get(), &render_pass_info, vk_allocation_callbacks, &vk_render_pass_); + device.device_get(), &render_pass_info, vk_allocation_callbacks, &vk_render_pass_); /* We might want to split frame-buffer and render pass. */ VkFramebufferCreateInfo framebuffer_create_info = {}; @@ -359,7 +360,7 @@ void VKFrameBuffer::render_pass_create() framebuffer_create_info.layers = 1; vkCreateFramebuffer( - context.device_get(), &framebuffer_create_info, vk_allocation_callbacks, &vk_framebuffer_); + device.device_get(), &framebuffer_create_info, vk_allocation_callbacks, &vk_framebuffer_); } void VKFrameBuffer::render_pass_free() @@ -370,9 +371,9 @@ void VKFrameBuffer::render_pass_free() } VK_ALLOCATION_CALLBACKS - VKContext &context = *VKContext::get(); - vkDestroyRenderPass(context.device_get(), vk_render_pass_, vk_allocation_callbacks); - vkDestroyFramebuffer(context.device_get(), vk_framebuffer_, vk_allocation_callbacks); + const VKDevice &device = VKBackend::get().device_get(); + vkDestroyRenderPass(device.device_get(), vk_render_pass_, vk_allocation_callbacks); + vkDestroyFramebuffer(device.device_get(), vk_framebuffer_, vk_allocation_callbacks); vk_render_pass_ = VK_NULL_HANDLE; vk_framebuffer_ = VK_NULL_HANDLE; } diff --git a/source/blender/gpu/vulkan/vk_index_buffer.cc b/source/blender/gpu/vulkan/vk_index_buffer.cc index 8094d41b028..a96adb2af66 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.cc +++ b/source/blender/gpu/vulkan/vk_index_buffer.cc @@ -18,9 +18,8 @@ void VKIndexBuffer::ensure_updated() return; } - VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { - allocate(context); + allocate(); } if (data_ != nullptr) { @@ -64,15 +63,14 @@ void VKIndexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data void VKIndexBuffer::strip_restart_indices() {} -void VKIndexBuffer::allocate(VKContext &context) +void VKIndexBuffer::allocate() { GPUUsageType usage = data_ == nullptr ? GPU_USAGE_DEVICE_ONLY : GPU_USAGE_STATIC; - buffer_.create(context, - size_get(), + buffer_.create(size_get(), usage, static_cast(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT)); - debug::object_label(&context, buffer_.vk_handle(), "IndexBuffer"); + debug::object_label(buffer_.vk_handle(), "IndexBuffer"); } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_index_buffer.hh b/source/blender/gpu/vulkan/vk_index_buffer.hh index 761b538cf8d..00a78337683 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.hh +++ b/source/blender/gpu/vulkan/vk_index_buffer.hh @@ -33,7 +33,7 @@ class VKIndexBuffer : public IndexBuf { private: void strip_restart_indices() override; - void allocate(VKContext &context); + void allocate(); void ensure_updated(); }; diff --git a/source/blender/gpu/vulkan/vk_pipeline.cc b/source/blender/gpu/vulkan/vk_pipeline.cc index bc0d471f5ac..1b738029af9 100644 --- a/source/blender/gpu/vulkan/vk_pipeline.cc +++ b/source/blender/gpu/vulkan/vk_pipeline.cc @@ -6,6 +6,7 @@ */ #include "vk_pipeline.hh" +#include "vk_backend.hh" #include "vk_context.hh" #include "vk_memory.hh" @@ -23,21 +24,20 @@ VKPipeline::VKPipeline(VkPipeline vk_pipeline, VKPipeline::~VKPipeline() { VK_ALLOCATION_CALLBACKS - VkDevice vk_device = VKContext::get()->device_get(); + const VKDevice &device = VKBackend::get().device_get(); if (vk_pipeline_ != VK_NULL_HANDLE) { - vkDestroyPipeline(vk_device, vk_pipeline_, vk_allocation_callbacks); + vkDestroyPipeline(device.device_get(), vk_pipeline_, vk_allocation_callbacks); } } VKPipeline VKPipeline::create_compute_pipeline( - VKContext &context, VkShaderModule compute_module, VkDescriptorSetLayout &descriptor_set_layout, VkPipelineLayout &pipeline_layout, const VKPushConstants::Layout &push_constants_layout) { VK_ALLOCATION_CALLBACKS - VkDevice vk_device = context.device_get(); + const VKDevice &device = VKBackend::get().device_get(); VkComputePipelineCreateInfo pipeline_info = {}; pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; pipeline_info.flags = 0; @@ -50,9 +50,12 @@ VKPipeline VKPipeline::create_compute_pipeline( pipeline_info.stage.pName = "main"; VkPipeline vk_pipeline; - if (vkCreateComputePipelines( - vk_device, nullptr, 1, &pipeline_info, vk_allocation_callbacks, &vk_pipeline) != - VK_SUCCESS) + if (vkCreateComputePipelines(device.device_get(), + nullptr, + 1, + &pipeline_info, + vk_allocation_callbacks, + &vk_pipeline) != VK_SUCCESS) { return VKPipeline(); } diff --git a/source/blender/gpu/vulkan/vk_pipeline.hh b/source/blender/gpu/vulkan/vk_pipeline.hh index 21547ac3c77..565b41ba41d 100644 --- a/source/blender/gpu/vulkan/vk_pipeline.hh +++ b/source/blender/gpu/vulkan/vk_pipeline.hh @@ -40,8 +40,7 @@ class VKPipeline : NonCopyable { return *this; } - static VKPipeline create_compute_pipeline(VKContext &context, - VkShaderModule compute_module, + static VKPipeline create_compute_pipeline(VkShaderModule compute_module, VkDescriptorSetLayout &descriptor_set_layout, VkPipelineLayout &pipeline_layouts, const VKPushConstants::Layout &push_constants_layout); diff --git a/source/blender/gpu/vulkan/vk_pixel_buffer.cc b/source/blender/gpu/vulkan/vk_pixel_buffer.cc index 667156b7a7d..94a6f71185a 100644 --- a/source/blender/gpu/vulkan/vk_pixel_buffer.cc +++ b/source/blender/gpu/vulkan/vk_pixel_buffer.cc @@ -13,12 +13,11 @@ namespace blender::gpu { VKPixelBuffer::VKPixelBuffer(int64_t size) : PixelBuffer(size) { - VKContext &context = *VKContext::get(); - buffer_.create(context, - size, + buffer_.create(size, GPU_USAGE_STATIC, static_cast(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)); + debug::object_label(buffer_.vk_handle(), "PixelBuffer"); } void *VKPixelBuffer::map() diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index 7118a56947f..77036778191 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -561,10 +561,9 @@ void VKShader::build_shader_module(Span spirv_module, VkShaderModule * create_info.codeSize = spirv_module.size() * sizeof(uint32_t); create_info.pCode = spirv_module.data(); - VKContext &context = *static_cast(VKContext::get()); - + const VKDevice &device = VKBackend::get().device_get(); VkResult result = vkCreateShaderModule( - context.device_get(), &create_info, vk_allocation_callbacks, r_shader_module); + device.device_get(), &create_info, vk_allocation_callbacks, r_shader_module); if (result != VK_SUCCESS) { compilation_failed_ = true; *r_shader_module = VK_NULL_HANDLE; @@ -580,29 +579,29 @@ VKShader::~VKShader() { VK_ALLOCATION_CALLBACKS - VkDevice device = context_->device_get(); + const VKDevice &device = VKBackend::get().device_get(); if (vertex_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, vertex_module_, vk_allocation_callbacks); + vkDestroyShaderModule(device.device_get(), vertex_module_, vk_allocation_callbacks); vertex_module_ = VK_NULL_HANDLE; } if (geometry_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, geometry_module_, vk_allocation_callbacks); + vkDestroyShaderModule(device.device_get(), geometry_module_, vk_allocation_callbacks); geometry_module_ = VK_NULL_HANDLE; } if (fragment_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, fragment_module_, vk_allocation_callbacks); + vkDestroyShaderModule(device.device_get(), fragment_module_, vk_allocation_callbacks); fragment_module_ = VK_NULL_HANDLE; } if (compute_module_ != VK_NULL_HANDLE) { - vkDestroyShaderModule(device, compute_module_, vk_allocation_callbacks); + vkDestroyShaderModule(device.device_get(), compute_module_, vk_allocation_callbacks); compute_module_ = VK_NULL_HANDLE; } if (pipeline_layout_ != VK_NULL_HANDLE) { - vkDestroyPipelineLayout(device, pipeline_layout_, vk_allocation_callbacks); + vkDestroyPipelineLayout(device.device_get(), pipeline_layout_, vk_allocation_callbacks); pipeline_layout_ = VK_NULL_HANDLE; } if (layout_ != VK_NULL_HANDLE) { - vkDestroyDescriptorSetLayout(device, layout_, vk_allocation_callbacks); + vkDestroyDescriptorSetLayout(device.device_get(), layout_, vk_allocation_callbacks); layout_ = VK_NULL_HANDLE; } } @@ -653,11 +652,11 @@ bool VKShader::finalize(const shader::ShaderCreateInfo *info) VKShaderInterface *vk_interface = new VKShaderInterface(); vk_interface->init(*info); - VkDevice vk_device = context_->device_get(); - if (!finalize_descriptor_set_layouts(vk_device, *vk_interface, *info)) { + const VKDevice &device = VKBackend::get().device_get(); + if (!finalize_descriptor_set_layouts(device.device_get(), *vk_interface, *info)) { return false; } - if (!finalize_pipeline_layout(vk_device, *vk_interface)) { + if (!finalize_pipeline_layout(device.device_get(), *vk_interface)) { return false; } @@ -668,7 +667,7 @@ bool VKShader::finalize(const shader::ShaderCreateInfo *info) BLI_assert((fragment_module_ != VK_NULL_HANDLE && info->tf_type_ == GPU_SHADER_TFB_NONE) || (fragment_module_ == VK_NULL_HANDLE && info->tf_type_ != GPU_SHADER_TFB_NONE)); BLI_assert(compute_module_ == VK_NULL_HANDLE); - result = finalize_graphics_pipeline(vk_device); + result = finalize_graphics_pipeline(device.device_get()); } else { BLI_assert(vertex_module_ == VK_NULL_HANDLE); @@ -676,11 +675,7 @@ bool VKShader::finalize(const shader::ShaderCreateInfo *info) BLI_assert(fragment_module_ == VK_NULL_HANDLE); BLI_assert(compute_module_ != VK_NULL_HANDLE); compute_pipeline_ = VKPipeline::create_compute_pipeline( - *context_, - compute_module_, - layout_, - pipeline_layout_, - vk_interface->push_constants_layout_get()); + compute_module_, layout_, pipeline_layout_, vk_interface->push_constants_layout_get()); result = compute_pipeline_.is_valid(); } diff --git a/source/blender/gpu/vulkan/vk_shader_interface.cc b/source/blender/gpu/vulkan/vk_shader_interface.cc index 930ef372ec7..ac0ba074bac 100644 --- a/source/blender/gpu/vulkan/vk_shader_interface.cc +++ b/source/blender/gpu/vulkan/vk_shader_interface.cc @@ -6,6 +6,7 @@ */ #include "vk_shader_interface.hh" +#include "vk_backend.hh" #include "vk_context.hh" namespace blender::gpu { @@ -47,9 +48,9 @@ void VKShaderInterface::init(const shader::ShaderCreateInfo &info) /* Reserve 1 uniform buffer for push constants fallback. */ size_t names_size = info.interface_names_size_; - VKContext &context = *VKContext::get(); + const VKDevice &device = VKBackend::get().device_get(); const VKPushConstants::StorageType push_constants_storage_type = - VKPushConstants::Layout::determine_storage_type(info, context.physical_device_limits_get()); + VKPushConstants::Layout::determine_storage_type(info, device.physical_device_limits_get()); if (push_constants_storage_type == VKPushConstants::StorageType::UNIFORM_BUFFER) { ubo_len_++; names_size += PUSH_CONSTANTS_FALLBACK_NAME_LEN + 1; diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.cc b/source/blender/gpu/vulkan/vk_storage_buffer.cc index 14c346206d0..3e050e46479 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.cc +++ b/source/blender/gpu/vulkan/vk_storage_buffer.cc @@ -15,26 +15,25 @@ namespace blender::gpu { void VKStorageBuffer::update(const void *data) { if (!buffer_.is_allocated()) { - VKContext &context = *VKContext::get(); - allocate(context); + allocate(); } buffer_.update(data); } -void VKStorageBuffer::allocate(VKContext &context) +void VKStorageBuffer::allocate() { - buffer_.create(context, - size_in_bytes_, + buffer_.create(size_in_bytes_, usage_, static_cast(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)); + debug::object_label(buffer_.vk_handle(), name_); } void VKStorageBuffer::bind(int slot) { VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { - allocate(context); + allocate(); } VKShader *shader = static_cast(context.shader); const VKShaderInterface &shader_interface = shader->interface_get(); @@ -49,7 +48,7 @@ void VKStorageBuffer::clear(uint32_t clear_value) { VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { - allocate(context); + allocate(); } buffer_.clear(context, clear_value); } @@ -63,11 +62,11 @@ void VKStorageBuffer::copy_sub(VertBuf * /*src*/, void VKStorageBuffer::read(void *data) { - VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { - allocate(context); + allocate(); } + VKContext &context = *VKContext::get(); VKCommandBuffer &command_buffer = context.command_buffer_get(); command_buffer.submit(); diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.hh b/source/blender/gpu/vulkan/vk_storage_buffer.hh index e5f57f4981d..02a4c5e49f7 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.hh +++ b/source/blender/gpu/vulkan/vk_storage_buffer.hh @@ -45,7 +45,7 @@ class VKStorageBuffer : public StorageBuf { } private: - void allocate(VKContext &context); + void allocate(); }; } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 26366655da8..925fd8a0252 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -25,9 +25,9 @@ VKTexture::~VKTexture() { VK_ALLOCATION_CALLBACKS - VKContext &context = *VKContext::get(); - vmaDestroyImage(context.mem_allocator_get(), vk_image_, allocation_); - vkDestroyImageView(context.device_get(), vk_image_view_, vk_allocation_callbacks); + const VKDevice &device = VKBackend::get().device_get(); + vmaDestroyImage(device.mem_allocator_get(), vk_image_, allocation_); + vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks); } void VKTexture::generate_mipmap() {} @@ -75,7 +75,7 @@ void *VKTexture::read(int mip, eGPUDataFormat format) size_t host_memory_size = sample_len * to_bytesize(format_, format); staging_buffer.create( - context, device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_DST_BIT); + device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_DST_BIT); VkBufferImageCopy region = {}; region.imageExtent.width = extent[0]; @@ -113,7 +113,7 @@ void VKTexture::update_sub( size_t device_memory_size = sample_len * to_bytesize(format_); staging_buffer.create( - context, device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); uint buffer_row_length = context.state_manager_get().texture_unpack_row_length_get(); if (buffer_row_length) { @@ -234,6 +234,7 @@ bool VKTexture::allocate() mip_size_get(0, extent); VKContext &context = *VKContext::get(); + const VKDevice &device = VKBackend::get().device_get(); VkImageCreateInfo image_info = {}; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.imageType = to_vk_image_type(type_); @@ -256,7 +257,7 @@ bool VKTexture::allocate() VkResult result; if (G.debug & G_DEBUG_GPU) { VkImageFormatProperties image_format = {}; - result = vkGetPhysicalDeviceImageFormatProperties(context.physical_device_get(), + result = vkGetPhysicalDeviceImageFormatProperties(device.physical_device_get(), image_info.format, image_info.imageType, image_info.tiling, @@ -272,7 +273,7 @@ bool VKTexture::allocate() VmaAllocationCreateInfo allocCreateInfo = {}; allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; allocCreateInfo.priority = 1.0f; - result = vmaCreateImage(context.mem_allocator_get(), + result = vmaCreateImage(device.mem_allocator_get(), &image_info, &allocCreateInfo, &vk_image_, @@ -281,7 +282,7 @@ bool VKTexture::allocate() if (result != VK_SUCCESS) { return false; } - debug::object_label(&context, vk_image_, name_); + debug::object_label( vk_image_, name_); /* Promote image to the correct layout. */ layout_ensure(context, VK_IMAGE_LAYOUT_GENERAL); @@ -298,8 +299,8 @@ bool VKTexture::allocate() image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; result = vkCreateImageView( - context.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_); - debug::object_label(&context, vk_image_view_, name_); + device.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_); + debug::object_label( vk_image_view_, name_); return result == VK_SUCCESS; } diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.cc b/source/blender/gpu/vulkan/vk_uniform_buffer.cc index 2ec593a5fd8..4dd427d0649 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.cc +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.cc @@ -15,34 +15,33 @@ namespace blender::gpu { void VKUniformBuffer::update(const void *data) { if (!buffer_.is_allocated()) { - VKContext &context = *VKContext::get(); - allocate(context); + allocate(); } buffer_.update(data); } -void VKUniformBuffer::allocate(VKContext &context) +void VKUniformBuffer::allocate() { - buffer_.create(context, size_in_bytes_, GPU_USAGE_STATIC, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); - debug::object_label(&context, buffer_.vk_handle(), name_); + buffer_.create(size_in_bytes_, GPU_USAGE_STATIC, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + debug::object_label(buffer_.vk_handle(), name_); } void VKUniformBuffer::clear_to_zero() { - VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { - allocate(context); + allocate(); } + VKContext &context = *VKContext::get(); buffer_.clear(context, 0); } void VKUniformBuffer::bind(int slot, shader::ShaderCreateInfo::Resource::BindType bind_type) { - VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { - allocate(context); + allocate(); } + VKContext &context = *VKContext::get(); VKShader *shader = static_cast(context.shader); const VKShaderInterface &shader_interface = shader->interface_get(); const VKDescriptorSet::Location location = shader_interface.descriptor_set_location(bind_type, diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.hh b/source/blender/gpu/vulkan/vk_uniform_buffer.hh index ee0f763578b..a31915cfce4 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.hh +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.hh @@ -38,7 +38,7 @@ class VKUniformBuffer : public UniformBuf, NonCopyable { } private: - void allocate(VKContext &context); + void allocate(); void bind(int slot, shader::ShaderCreateInfo::Resource::BindType bind_type); }; diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index dc7ae6aed74..1147df5f646 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -20,11 +20,11 @@ VKVertexBuffer::~VKVertexBuffer() void VKVertexBuffer::bind_as_ssbo(uint binding) { - VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { - allocate(context); + allocate(); } + VKContext &context = *VKContext::get(); VKShader *shader = static_cast(context.shader); const VKShaderInterface &shader_interface = shader->interface_get(); const VKDescriptorSet::Location location = shader_interface.descriptor_set_location( @@ -68,13 +68,13 @@ void VKVertexBuffer::upload_data() {} void VKVertexBuffer::duplicate_data(VertBuf * /*dst*/) {} -void VKVertexBuffer::allocate(VKContext &context) +void VKVertexBuffer::allocate() { - buffer_.create(context, - size_used_get(), + buffer_.create(size_used_get(), usage_, static_cast(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)); + debug::object_label(buffer_.vk_handle(), "VertexBuffer"); } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.hh b/source/blender/gpu/vulkan/vk_vertex_buffer.hh index bbae86ae07f..faae248f4f9 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.hh +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.hh @@ -39,7 +39,7 @@ class VKVertexBuffer : public VertBuf { void duplicate_data(VertBuf *dst) override; private: - void allocate(VKContext &context); + void allocate(); }; } // namespace blender::gpu -- 2.30.2 From eb5d6845c33dbd5a54af8e9a725017111d29dc9d Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 4 May 2023 10:06:03 +0200 Subject: [PATCH 2/2] Remove comment --- intern/ghost/intern/GHOST_ContextVK.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 23a3a2dacf7..32c780bc868 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -383,7 +383,6 @@ GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual, GHOST_ContextVK::~GHOST_ContextVK() { - // TODO: see if we can use a usage counter to free the global device. if (vulkan_device.has_value()) { GHOST_DeviceVK &device_vk = *vulkan_device; device_vk.wait_idle(); -- 2.30.2