This PR implements #126353; In short: keep discard list as part of swap chain images. This allows better determination when resources are actually not in use anymore. ## Resource pool Resource pools keep track of the resources for a swap chain image. In Blender this is a bit more complicated due to the way GPUContext work. A single thread can have multiple contexts. Some of them have a swap chain (GHOST Window) other don't (draw manager). The resource pool should be shared between the contexts running on the same thread. When opening multiple windows there are also multiple swap chains to consider. ### Discard pile Resource handles that are deleted and stored in the discard pile. When we are sure that these resources are not used on the GPU anymore these are destroyed. ### Reusable resources There are other resources as well like: - Descriptor sets - Descriptor pools ## Open issues There are some limitations that require future PRs to fix including: - Background rendering - Handling multiple windows - Improve CPU/GPU synchronization - Reuse staging buffers Pull Request: https://projects.blender.org/blender/blender/pulls/126353
87 lines
2.9 KiB
C++
87 lines
2.9 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#include "vk_image_view.hh"
|
|
#include "vk_backend.hh"
|
|
#include "vk_debug.hh"
|
|
#include "vk_device.hh"
|
|
#include "vk_memory.hh"
|
|
#include "vk_texture.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
static VkFormat to_non_srgb_format(const VkFormat format)
|
|
{
|
|
switch (format) {
|
|
case VK_FORMAT_R8G8B8_SRGB:
|
|
return VK_FORMAT_R8G8B8_UNORM;
|
|
case VK_FORMAT_R8G8B8A8_SRGB:
|
|
return VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return format;
|
|
}
|
|
|
|
VKImageView::VKImageView(VKTexture &texture, const VKImageViewInfo &info, StringRefNull name)
|
|
: info(info)
|
|
{
|
|
const VkImageAspectFlags allowed_bits = VK_IMAGE_ASPECT_COLOR_BIT |
|
|
(info.use_stencil ? VK_IMAGE_ASPECT_STENCIL_BIT :
|
|
VK_IMAGE_ASPECT_DEPTH_BIT);
|
|
eGPUTextureFormat device_format = texture.device_format_get();
|
|
VkImageAspectFlags image_aspect = to_vk_image_aspect_flag_bits(device_format) & allowed_bits;
|
|
|
|
vk_format_ = to_vk_format(device_format);
|
|
if (texture.format_flag_get() & GPU_FORMAT_SRGB && !info.use_srgb) {
|
|
vk_format_ = to_non_srgb_format(vk_format_);
|
|
}
|
|
|
|
VK_ALLOCATION_CALLBACKS
|
|
VkImageViewCreateInfo image_view_info = {};
|
|
image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
image_view_info.image = texture.vk_image_handle();
|
|
image_view_info.viewType = to_vk_image_view_type(texture.type_get(), info.usage, info.arrayed);
|
|
image_view_info.format = vk_format_;
|
|
image_view_info.components.r = to_vk_component_swizzle(info.swizzle[0]);
|
|
image_view_info.components.g = to_vk_component_swizzle(info.swizzle[1]);
|
|
image_view_info.components.b = to_vk_component_swizzle(info.swizzle[2]);
|
|
image_view_info.components.a = to_vk_component_swizzle(info.swizzle[3]);
|
|
image_view_info.subresourceRange.aspectMask = image_aspect;
|
|
image_view_info.subresourceRange.baseMipLevel = info.mip_range.first();
|
|
image_view_info.subresourceRange.levelCount = info.mip_range.size();
|
|
image_view_info.subresourceRange.baseArrayLayer = info.layer_range.first();
|
|
image_view_info.subresourceRange.layerCount = info.layer_range.size();
|
|
|
|
const VKDevice &device = VKBackend::get().device;
|
|
vkCreateImageView(
|
|
device.vk_handle(), &image_view_info, vk_allocation_callbacks, &vk_image_view_);
|
|
debug::object_label(vk_image_view_, name.c_str());
|
|
}
|
|
|
|
VKImageView::VKImageView(VKImageView &&other) : info(other.info)
|
|
{
|
|
vk_image_view_ = other.vk_image_view_;
|
|
other.vk_image_view_ = VK_NULL_HANDLE;
|
|
vk_format_ = other.vk_format_;
|
|
other.vk_format_ = VK_FORMAT_UNDEFINED;
|
|
}
|
|
|
|
VKImageView::~VKImageView()
|
|
{
|
|
if (vk_image_view_ != VK_NULL_HANDLE) {
|
|
VKDevice &device = VKBackend::get().device;
|
|
device.discard_pool_for_current_thread().discard_image_view(vk_image_view_);
|
|
vk_image_view_ = VK_NULL_HANDLE;
|
|
}
|
|
vk_format_ = VK_FORMAT_UNDEFINED;
|
|
}
|
|
|
|
} // namespace blender::gpu
|