Merge branch 'blender-v5.0-release'
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
@@ -715,7 +716,10 @@ GHOST_ContextVK::~GHOST_ContextVK()
|
||||
GHOST_InstanceVK &instance_vk = vulkan_instance.value();
|
||||
GHOST_DeviceVK &device_vk = instance_vk.device.value();
|
||||
device_vk.wait_idle();
|
||||
|
||||
for (VkFence fence : fence_pile_) {
|
||||
vkDestroyFence(device_vk.vk_device, fence, nullptr);
|
||||
}
|
||||
fence_pile_.clear();
|
||||
destroySwapchain();
|
||||
|
||||
if (surface_ != VK_NULL_HANDLE) {
|
||||
@@ -760,6 +764,9 @@ GHOST_TSuccess GHOST_ContextVK::swapBufferAcquire()
|
||||
if (submission_frame_data.submission_fence) {
|
||||
vkWaitForFences(vk_device, 1, &submission_frame_data.submission_fence, true, UINT64_MAX);
|
||||
}
|
||||
for (VkSwapchainKHR swapchain : submission_frame_data.discard_pile.swapchains) {
|
||||
this->destroySwapchainPresentFences(swapchain);
|
||||
}
|
||||
submission_frame_data.discard_pile.destroy(vk_device);
|
||||
|
||||
const bool use_hdr_swapchain = hdr_info_ &&
|
||||
@@ -842,6 +849,42 @@ GHOST_TSuccess GHOST_ContextVK::swapBufferAcquire()
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
VkFence GHOST_ContextVK::getFence()
|
||||
{
|
||||
if (!fence_pile_.empty()) {
|
||||
VkFence fence = fence_pile_.back();
|
||||
fence_pile_.pop_back();
|
||||
return fence;
|
||||
}
|
||||
GHOST_DeviceVK &device_vk = vulkan_instance->device.value();
|
||||
VkFence fence = VK_NULL_HANDLE;
|
||||
const VkFenceCreateInfo fence_create_info = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
|
||||
vkCreateFence(device_vk.vk_device, &fence_create_info, nullptr, &fence);
|
||||
return fence;
|
||||
}
|
||||
|
||||
void GHOST_ContextVK::setPresentFence(VkSwapchainKHR swapchain, VkFence present_fence)
|
||||
{
|
||||
if (present_fence == VK_NULL_HANDLE) {
|
||||
return;
|
||||
}
|
||||
present_fences_[swapchain].push_back(present_fence);
|
||||
GHOST_DeviceVK &device_vk = vulkan_instance->device.value();
|
||||
/** Recycle signaled fences. */
|
||||
for (std::pair<const VkSwapchainKHR, std::vector<VkFence>> &item : present_fences_) {
|
||||
std::vector<VkFence>::iterator end = item.second.end();
|
||||
std::vector<VkFence>::iterator it = std::remove_if(
|
||||
item.second.begin(), item.second.end(), [&](const VkFence fence) {
|
||||
if (vkGetFenceStatus(device_vk.vk_device, fence) == VK_NOT_READY) {
|
||||
return false;
|
||||
}
|
||||
vkResetFences(device_vk.vk_device, 1, &fence);
|
||||
fence_pile_.push_back(fence);
|
||||
return true;
|
||||
});
|
||||
item.second.erase(it, end);
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_ContextVK::swapBufferRelease()
|
||||
{
|
||||
@@ -894,7 +937,18 @@ GHOST_TSuccess GHOST_ContextVK::swapBufferRelease()
|
||||
VkResult present_result = VK_SUCCESS;
|
||||
{
|
||||
std::scoped_lock lock(device_vk.queue_mutex);
|
||||
VkSwapchainPresentFenceInfoEXT fence_info{VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT};
|
||||
VkFence present_fence = VK_NULL_HANDLE;
|
||||
if (device_vk.use_vk_ext_swapchain_maintenance_1) {
|
||||
present_fence = this->getFence();
|
||||
|
||||
fence_info.swapchainCount = 1;
|
||||
fence_info.pFences = &present_fence;
|
||||
|
||||
present_info.pNext = &fence_info;
|
||||
}
|
||||
present_result = vkQueuePresentKHR(device_vk.generic_queue, &present_info);
|
||||
this->setPresentFence(swapchain_, present_fence);
|
||||
}
|
||||
acquired_swapchain_image_index_.reset();
|
||||
|
||||
@@ -1312,11 +1366,25 @@ GHOST_TSuccess GHOST_ContextVK::recreateSwapchain(bool use_hdr_swapchain)
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
void GHOST_ContextVK::destroySwapchainPresentFences(VkSwapchainKHR swapchain)
|
||||
{
|
||||
GHOST_DeviceVK &device_vk = vulkan_instance.value().device.value();
|
||||
const std::vector<VkFence> &fences = present_fences_[swapchain];
|
||||
if (!fences.empty()) {
|
||||
vkWaitForFences(device_vk.vk_device, fences.size(), fences.data(), VK_TRUE, UINT64_MAX);
|
||||
for (VkFence fence : fences) {
|
||||
vkDestroyFence(device_vk.vk_device, fence, nullptr);
|
||||
}
|
||||
}
|
||||
present_fences_.erase(swapchain);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_ContextVK::destroySwapchain()
|
||||
{
|
||||
GHOST_DeviceVK &device_vk = vulkan_instance.value().device.value();
|
||||
|
||||
if (swapchain_ != VK_NULL_HANDLE) {
|
||||
this->destroySwapchainPresentFences(swapchain_);
|
||||
vkDestroySwapchainKHR(device_vk.vk_device, swapchain_, nullptr);
|
||||
}
|
||||
device_vk.wait_idle();
|
||||
@@ -1325,6 +1393,9 @@ GHOST_TSuccess GHOST_ContextVK::destroySwapchain()
|
||||
}
|
||||
swapchain_images_.clear();
|
||||
for (GHOST_Frame &frame_data : frame_data_) {
|
||||
for (VkSwapchainKHR swapchain : frame_data.discard_pile.swapchains) {
|
||||
this->destroySwapchainPresentFences(swapchain);
|
||||
}
|
||||
frame_data.destroy(device_vk.vk_device);
|
||||
}
|
||||
frame_data_.clear();
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
@@ -247,8 +248,15 @@ class GHOST_ContextVK : public GHOST_Context {
|
||||
std::function<void(GHOST_VulkanOpenXRData *)> openxr_acquire_framebuffer_image_callback_;
|
||||
std::function<void(GHOST_VulkanOpenXRData *)> openxr_release_framebuffer_image_callback_;
|
||||
|
||||
std::vector<VkFence> fence_pile_;
|
||||
std::map<VkSwapchainKHR, std::vector<VkFence>> present_fences_;
|
||||
|
||||
const char *getPlatformSpecificSurfaceExtension() const;
|
||||
GHOST_TSuccess recreateSwapchain(bool use_hdr_swapchain);
|
||||
GHOST_TSuccess initializeFrameData();
|
||||
GHOST_TSuccess destroySwapchain();
|
||||
|
||||
VkFence getFence();
|
||||
void setPresentFence(VkSwapchainKHR swapchain, VkFence fence);
|
||||
void destroySwapchainPresentFences(VkSwapchainKHR swapchain);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user