MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ download_image()

std::optional< ImageData > MayaFlux::IO::download_image ( const std::shared_ptr< Core::VKImage > &  image)

Download pixel data from a GPU-resident VKImage into host ImageData.

Performs a blocking GPU->host transfer via TextureLoom::download_data, allocating a host buffer of the appropriate variant for the image format. The source image is restored to eShaderReadOnlyOptimal / eFragmentShader after the copy; pass a different restore layout/stage via the overload if the image was, for example, in a compute write state.

Multi-layer and multi-mip images are downloaded at layer 0, mip 0 only. Array and mipmap export is a separate concern.

Parameters
imageFully-initialized VKImage to read from.
Returns
Populated ImageData, or std::nullopt on failure.

Definition at line 51 of file ImageExport.cpp.

53{
54 if (!image) {
55 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
56 "download_image: null image");
57 return std::nullopt;
58 }
59
60 const vk::Format vk_format = image->get_format();
61 const auto format_opt = Portal::Graphics::TextureLoom::from_vulkan_format(vk_format);
62 if (!format_opt) {
63 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
64 "download_image: vk::Format {} has no ImageFormat mapping",
65 vk::to_string(vk_format));
66 return std::nullopt;
67 }
68
69 const ImageFormat format = *format_opt;
70 const uint32_t channels = Portal::Graphics::TextureLoom::get_channel_count(format);
71 if (channels == 0) {
72 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
73 "download_image: zero channels for format {}",
74 static_cast<int>(format));
75 return std::nullopt;
76 }
77
78 const uint32_t width = image->get_width();
79 const uint32_t height = image->get_height();
80 if (width == 0 || height == 0) {
81 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
82 "download_image: zero dimensions {}x{}", width, height);
83 return std::nullopt;
84 }
85
86 const size_t pixel_count = static_cast<size_t>(width) * height;
87 const size_t mip0_bytes = pixel_count * TextureLoom::get_bytes_per_pixel(format);
88
89 ImageData result;
90 result.width = width;
91 result.height = height;
92 result.channels = channels;
93 result.format = format;
94
95 if (!emplace_variant_for_format(result, format, pixel_count, channels)) {
96 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
97 "download_image: unsupported bytes-per-element for format {}",
98 static_cast<int>(format));
99 return std::nullopt;
100 }
101
102 TextureLoom::instance().download_data_async(
103 image,
104 const_cast<void*>(result.data()),
105 mip0_bytes);
106
107 if (!result.is_consistent()) {
108 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
109 "download_image: resulting ImageData failed is_consistent()");
110 return std::nullopt;
111 }
112
113 MF_DEBUG(Journal::Component::IO, Journal::Context::FileIO,
114 "download_image: {}x{}, {} channels, {} bytes",
115 width, height, channels, mip0_bytes);
116
117 return result;
118}
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
IO::ImageData image
uint32_t width
std::string format(format_string< std::remove_cvref_t< Args >... > fmt_str, Args &&... args)
Definition Format.hpp:30

References MayaFlux::IO::ImageData::channels, MayaFlux::IO::ImageData::data(), MayaFlux::Journal::FileIO, MayaFlux::IO::ImageData::format, MayaFlux::Portal::Graphics::TextureLoom::from_vulkan_format(), MayaFlux::Portal::Graphics::TextureLoom::get_channel_count(), MayaFlux::IO::ImageData::height, image, MayaFlux::Journal::IO, MayaFlux::IO::ImageData::is_consistent(), MF_DEBUG, MF_ERROR, MayaFlux::IO::ImageData::width, and width.

Referenced by download_texture_buffer(), save_image(), and MayaFlux::IO::IOManager::save_image().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: