graphics: simplify image allocation

This commit is contained in:
nmzik
2026-09-08 11:17:23 +04:00
parent 574e687734
commit 80a18e82b7
6 changed files with 107 additions and 51 deletions
+1 -8
View File
@@ -15,7 +15,6 @@
namespace Libs::Graphics {
struct VulkanImage;
struct VulkanMemory;
inline constexpr uint32_t VULKAN_TARGET_API_VERSION = VK_API_VERSION_1_3;
@@ -117,12 +116,6 @@ private:
m_image_format_properties;
};
struct VulkanMemory {
vk::MemoryPropertyFlags property = {};
vk::MemoryPropertyFlags preferred_property = {};
VmaAllocation allocation = nullptr;
};
struct VulkanImageState {
vk::PipelineStageFlags2 pl_stage = vk::PipelineStageFlagBits2::eAllCommands;
vk::AccessFlags2 access_mask = vk::AccessFlagBits2::eNone;
@@ -144,7 +137,7 @@ struct VulkanImage {
vk::Image image = nullptr;
VulkanImageState state;
std::vector<VulkanImageState> subresource_states;
Graphics::VulkanMemory memory;
VmaAllocation allocation = nullptr;
};
+10 -20
View File
@@ -661,26 +661,17 @@ Image::Image(GraphicContext& graphics, CommandScheduler& scheduler, const ImageI
return;
}
backing.format = info.pixel_format;
backing.image_type = HostImageType(info.type);
backing.extent = info.extent;
backing.layers = info.IsVolume() ? 1u : info.resources.layers;
backing.mip_levels = info.resources.levels;
backing.samples = info.samples;
backing.flags = ImageCreateFlags(graphics, info);
backing.usage = ImageUsageFlags(graphics, info);
vk::ImageCreateInfo create {};
create.flags = backing.flags;
create.imageType = backing.image_type;
create.extent = backing.extent;
create.mipLevels = backing.mip_levels;
create.arrayLayers = backing.layers;
create.format = backing.format;
create.flags = ImageCreateFlags(graphics, info);
create.imageType = HostImageType(info.type);
create.extent = info.extent;
create.mipLevels = info.resources.levels;
create.arrayLayers = info.IsVolume() ? 1u : info.resources.layers;
create.format = info.pixel_format;
create.tiling = vk::ImageTiling::eOptimal;
create.initialLayout = backing.state.layout;
create.usage = backing.usage;
create.samples = vulkan_sample_count(backing.samples);
create.initialLayout = vk::ImageLayout::eUndefined;
create.usage = ImageUsageFlags(graphics, info);
create.samples = vulkan_sample_count(info.samples);
vk::ImageFormatProperties properties {};
if (graphics.GetImageFormatProperties(create.format, create.imageType, create.tiling,
@@ -691,10 +682,9 @@ Image::Image(GraphicContext& graphics, CommandScheduler& scheduler, const ImageI
"flags=0x%x samples=%u\n",
static_cast<int>(create.format), static_cast<int>(create.imageType),
static_cast<vk::ImageUsageFlags::MaskType>(create.usage),
static_cast<vk::ImageCreateFlags::MaskType>(create.flags), backing.samples);
static_cast<vk::ImageCreateFlags::MaskType>(create.flags), info.samples);
}
backing.memory.property = vk::MemoryPropertyFlagBits::eDeviceLocal;
if (!graphics.CreateImage(create, backing)) {
EXIT("failed to create image: extent=%ux%ux%u format=%d layers=%u levels=%u\n",
create.extent.width, create.extent.height, create.extent.depth,
+18 -11
View File
@@ -130,35 +130,42 @@ uint64_t GraphicContext::GetTotalMemoryBudget() const {
bool GraphicContext::CreateImage(const vk::ImageCreateInfo& image_info, VulkanImage& image) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(allocator == nullptr || image.image != nullptr || image.memory.allocation != nullptr);
EXIT_IF(allocator == nullptr || image.image != nullptr || image.allocation != nullptr);
auto& memory = image.memory;
VmaAllocationCreateInfo alloc_info {};
alloc_info.requiredFlags = static_cast<vk::MemoryPropertyFlags::MaskType>(memory.property);
alloc_info.preferredFlags =
static_cast<vk::MemoryPropertyFlags::MaskType>(memory.preferred_property);
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
vk::Image::CType native_image = VK_NULL_HANDLE;
const auto result = static_cast<vk::Result>(
vmaCreateImage(allocator, static_cast<const vk::ImageCreateInfo::NativeType*>(image_info),
&alloc_info, &native_image, &memory.allocation, nullptr));
&alloc_info, &native_image, &image.allocation, nullptr));
image.image = native_image;
if (result != vk::Result::eSuccess) {
LogMemoryBudget();
return false;
}
image.format = image_info.format;
image.image_type = image_info.imageType;
image.extent = image_info.extent;
image.layers = image_info.arrayLayers;
image.mip_levels = image_info.mipLevels;
image.samples = static_cast<uint32_t>(image_info.samples);
image.usage = image_info.usage;
image.flags = image_info.flags;
image.state = {.layout = image_info.initialLayout};
image.subresource_states.clear();
return true;
}
void GraphicContext::DeleteImage(VulkanImage& image) {
KYTY_PROFILER_FUNCTION();
EXIT_IF(allocator == nullptr || image.image == nullptr || image.memory.allocation == nullptr);
EXIT_IF(allocator == nullptr || image.image == nullptr || image.allocation == nullptr);
auto& memory = image.memory;
vmaDestroyImage(allocator, image.image, memory.allocation);
image.image = nullptr;
memory.allocation = nullptr;
vmaDestroyImage(allocator, image.image, image.allocation);
image.image = nullptr;
image.allocation = nullptr;
}
} // namespace Libs::Graphics
+3 -12
View File
@@ -191,24 +191,15 @@ void Presenter::Frame::Configure(GraphicContext& graphics, vk::Extent2D extent,
}
if (dst.image != nullptr) {
graphics.DeleteImage(dst);
dst.memory = {};
}
dst.extent = {extent.width, extent.height, 1};
dst.format = format;
dst.layers = 1;
dst.mip_levels = 1;
dst.state = {};
dst.subresource_states.clear();
dst.memory.property = vk::MemoryPropertyFlagBits::eDeviceLocal;
vk::ImageCreateInfo create {};
create.sType = vk::StructureType::eImageCreateInfo;
create.imageType = vk::ImageType::e2D;
create.extent = {dst.extent.width, dst.extent.height, 1};
create.extent = {extent.width, extent.height, 1};
create.mipLevels = 1;
create.arrayLayers = 1;
create.format = dst.format;
create.format = format;
create.tiling = vk::ImageTiling::eOptimal;
create.initialLayout = vk::ImageLayout::eUndefined;
create.usage = vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst;
@@ -216,7 +207,7 @@ void Presenter::Frame::Configure(GraphicContext& graphics, vk::Extent2D extent,
create.samples = vk::SampleCountFlagBits::e1;
if (!graphics.CreateImage(create, dst)) {
EXIT("failed to allocate prepared presentation image, extent=%ux%u format=%d\n",
dst.extent.width, dst.extent.height, static_cast<int>(dst.format));
extent.width, extent.height, static_cast<int>(format));
}
}