Vulkan: Remove resource pools
Multiple previous changes made resource pools obsolete. Resource pools were used to keep track of resources when the frame is rendered. Multiple frames can be rendered at the same time and resources could overlap. This has been replaced (not this commit) to be part of the render graph and when an submission has completed the resources are recycled. Continuation of: https://projects.blender.org/blender/blender/pulls/145408 Pull Request: https://projects.blender.org/blender/blender/pulls/145511
This commit is contained in:
@@ -603,10 +603,11 @@ GHOST_ContextVK::GHOST_ContextVK(const GHOST_ContextParams &context_params,
|
||||
hdr_info_(hdr_info),
|
||||
surface_(VK_NULL_HANDLE),
|
||||
swapchain_(VK_NULL_HANDLE),
|
||||
frame_data_(GHOST_FRAMES_IN_FLIGHT),
|
||||
frame_data_(2),
|
||||
render_frame_(0),
|
||||
use_hdr_swapchain_(false)
|
||||
{
|
||||
frame_data_.reserve(5);
|
||||
}
|
||||
|
||||
GHOST_ContextVK::~GHOST_ContextVK()
|
||||
@@ -1160,7 +1161,11 @@ GHOST_TSuccess GHOST_ContextVK::recreateSwapchain(bool use_hdr_swapchain)
|
||||
/* Some platforms require a minimum amount of render frames that is larger than we expect. When
|
||||
* that happens we should increase the number of frames in flight. We could also consider
|
||||
* splitting the frame in flight and image specific data. */
|
||||
assert(actual_image_count <= GHOST_FRAMES_IN_FLIGHT);
|
||||
if (actual_image_count > frame_data_.size()) {
|
||||
CLOG_TRACE(&LOG, "Vulkan: Increasing frame data to %u frames", actual_image_count);
|
||||
assert(actual_image_count <= frame_data_.capacity());
|
||||
frame_data_.resize(actual_image_count);
|
||||
}
|
||||
swapchain_images_.resize(actual_image_count);
|
||||
std::vector<VkImage> swapchain_images(actual_image_count);
|
||||
vkGetSwapchainImagesKHR(device, swapchain_, &actual_image_count, swapchain_images.data());
|
||||
@@ -1184,7 +1189,9 @@ GHOST_TSuccess GHOST_ContextVK::recreateSwapchain(bool use_hdr_swapchain)
|
||||
* to fill in where the handle is `VK_NULL_HANDLE`. */
|
||||
/* Previous handles from the frame data cannot be used and should be discarded. */
|
||||
for (GHOST_Frame &frame : frame_data_) {
|
||||
discard_pile.semaphores.push_back(frame.acquire_semaphore);
|
||||
if (frame.acquire_semaphore != VK_NULL_HANDLE) {
|
||||
discard_pile.semaphores.push_back(frame.acquire_semaphore);
|
||||
}
|
||||
frame.acquire_semaphore = VK_NULL_HANDLE;
|
||||
}
|
||||
if (old_swapchain) {
|
||||
|
||||
@@ -91,15 +91,6 @@ struct GHOST_Frame {
|
||||
void destroy(VkDevice vk_device);
|
||||
};
|
||||
|
||||
/**
|
||||
* The number of frames that GHOST manages.
|
||||
*
|
||||
* This must be kept in sync with any frame-aligned resources in the
|
||||
* Vulkan backend. Notably, VKThreadData::resource_pools_count must
|
||||
* match this value.
|
||||
*/
|
||||
constexpr static uint32_t GHOST_FRAMES_IN_FLIGHT = 5;
|
||||
|
||||
class GHOST_ContextVK : public GHOST_Context {
|
||||
friend class GHOST_XrGraphicsBindingVulkan;
|
||||
friend class GHOST_XrGraphicsBindingVulkanD3D;
|
||||
|
||||
@@ -56,15 +56,11 @@ VKContext::~VKContext()
|
||||
this->process_frame_timings();
|
||||
}
|
||||
|
||||
void VKContext::sync_backbuffer(bool cycle_resource_pool)
|
||||
void VKContext::sync_backbuffer()
|
||||
{
|
||||
if (ghost_window_) {
|
||||
GHOST_VulkanSwapChainData swap_chain_data = {};
|
||||
GHOST_GetVulkanSwapChainFormat((GHOST_WindowHandle)ghost_window_, &swap_chain_data);
|
||||
VKThreadData &thread_data = thread_data_.value().get();
|
||||
if (cycle_resource_pool) {
|
||||
thread_data.resource_pool_next();
|
||||
}
|
||||
|
||||
const bool reset_framebuffer = swap_chain_format_.format !=
|
||||
swap_chain_data.surface_format.format ||
|
||||
@@ -132,7 +128,7 @@ void VKContext::activate()
|
||||
|
||||
is_active_ = true;
|
||||
|
||||
sync_backbuffer(false);
|
||||
sync_backbuffer();
|
||||
|
||||
immActivate();
|
||||
}
|
||||
@@ -216,7 +212,7 @@ VKDescriptorPools &VKContext::descriptor_pools_get()
|
||||
|
||||
VKDescriptorSetTracker &VKContext::descriptor_set_get()
|
||||
{
|
||||
return thread_data_.value().get().resource_pool_get().descriptor_set;
|
||||
return thread_data_.value().get().descriptor_set;
|
||||
}
|
||||
|
||||
VKStateManager &VKContext::state_manager_get() const
|
||||
@@ -451,7 +447,7 @@ void VKContext::swap_buffers_pre_handler(const GHOST_VulkanSwapChainData &swap_c
|
||||
|
||||
void VKContext::swap_buffers_post_handler()
|
||||
{
|
||||
sync_backbuffer(true);
|
||||
sync_backbuffer();
|
||||
}
|
||||
|
||||
void VKContext::specialization_constants_set(
|
||||
|
||||
@@ -137,7 +137,7 @@ class VKContext : public Context, NonCopyable {
|
||||
VKVertexAttributeObject &vao,
|
||||
render_graph::VKPipelineData &r_pipeline_data);
|
||||
|
||||
void sync_backbuffer(bool cycle_resource_pool);
|
||||
void sync_backbuffer();
|
||||
|
||||
static VKContext *get()
|
||||
{
|
||||
|
||||
@@ -645,11 +645,6 @@ void VKDevice::debug_print()
|
||||
const bool is_main = pthread_equal(thread_data->thread_id, pthread_self());
|
||||
os << "ThreadData" << (is_main ? " (main-thread)" : "") << ")\n";
|
||||
os << " Rendering_depth: " << thread_data->rendering_depth << "\n";
|
||||
for (int resource_pool_index : IndexRange(thread_data->resource_pools.size())) {
|
||||
const bool is_active = thread_data->resource_pool_index == resource_pool_index;
|
||||
os << " Resource Pool (index=" << resource_pool_index << (is_active ? " active" : "")
|
||||
<< ")\n";
|
||||
}
|
||||
}
|
||||
os << "Discard pool\n";
|
||||
debug_print(os, orphaned_data);
|
||||
|
||||
@@ -106,26 +106,12 @@ struct VKWorkarounds {
|
||||
* Shared resources between contexts that run in the same thread.
|
||||
*/
|
||||
class VKThreadData : public NonCopyable, NonMovable {
|
||||
/**
|
||||
* The number of resource pools is aligned to the number of frames
|
||||
* in flight used by GHOST. Therefore, this constant *must* always
|
||||
* match GHOST_ContextVK's GHOST_FRAMES_IN_FLIGHT.
|
||||
*/
|
||||
static constexpr uint32_t resource_pools_count = 5;
|
||||
|
||||
public:
|
||||
/** Thread ID this instance belongs to. */
|
||||
pthread_t thread_id;
|
||||
/**
|
||||
* Index of the active resource pool. Is in sync with the active swap-chain image or cycled when
|
||||
* rendering.
|
||||
*
|
||||
* NOTE: Initialized to `UINT32_MAX` to detect first change.
|
||||
*/
|
||||
uint32_t resource_pool_index = UINT32_MAX;
|
||||
std::array<VKResourcePool, resource_pools_count> resource_pools;
|
||||
|
||||
VKDescriptorPools descriptor_pools;
|
||||
VKDescriptorSetTracker descriptor_set;
|
||||
|
||||
/**
|
||||
* The current rendering depth.
|
||||
*
|
||||
@@ -137,28 +123,6 @@ class VKThreadData : public NonCopyable, NonMovable {
|
||||
int32_t rendering_depth = 0;
|
||||
|
||||
VKThreadData(VKDevice &device, pthread_t thread_id);
|
||||
|
||||
/**
|
||||
* Get the active resource pool.
|
||||
*/
|
||||
VKResourcePool &resource_pool_get()
|
||||
{
|
||||
if (resource_pool_index >= resource_pools.size()) {
|
||||
return resource_pools[0];
|
||||
}
|
||||
return resource_pools[resource_pool_index];
|
||||
}
|
||||
|
||||
/** Activate the next resource pool. */
|
||||
void resource_pool_next()
|
||||
{
|
||||
if (resource_pool_index == UINT32_MAX) {
|
||||
resource_pool_index = 1;
|
||||
}
|
||||
else {
|
||||
resource_pool_index = (resource_pool_index + 1) % resource_pools_count;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class VKDevice : public NonCopyable {
|
||||
|
||||
@@ -143,9 +143,4 @@ class VKDiscardPool {
|
||||
static VKDiscardPool &discard_pool_get();
|
||||
};
|
||||
|
||||
class VKResourcePool {
|
||||
|
||||
public:
|
||||
VKDescriptorSetTracker descriptor_set;
|
||||
};
|
||||
} // namespace blender::gpu
|
||||
|
||||
Reference in New Issue
Block a user