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

◆ blit_image()

bool MayaFlux::Core::BackendResourceManager::blit_image ( const std::shared_ptr< VKImage > &  src,
const std::shared_ptr< VKImage > &  dst,
const vk::ImageBlit &  region,
vk::Filter  filter,
bool  deferred = false 
)

Blit a region of one image into a region of another.

Scales with filter and converts between supported formats. The subresources in region choose the array layers. Both images are returned to the layout they held, or shader read when it was transient.

Parameters
srcSource image.
dstDestination image, distinct from src.
regionSubresources and offsets.
filterNearest or linear.
deferredRecord for deferred submission.
Returns
True if the blit was recorded or executed.

Definition at line 1140 of file BackendResoureManager.cpp.

1146{
1147 if (!src || !dst || src == dst) {
1149 "blit_image: source and destination must be two distinct initialised images");
1150 return false;
1151 }
1152
1153 if (!supports_blit(src->get_format(), dst->get_format(), filter)) {
1155 "blit_image: formats {} to {} do not support a {} blit",
1156 vk::to_string(src->get_format()), vk::to_string(dst->get_format()), vk::to_string(filter));
1157 return false;
1158 }
1159
1160 const auto settled_layout = [](const std::shared_ptr<VKImage>& image) {
1161 const auto layout = image->get_current_layout();
1162 const bool transient = layout == vk::ImageLayout::eUndefined
1163 || layout == vk::ImageLayout::eTransferSrcOptimal
1164 || layout == vk::ImageLayout::eTransferDstOptimal;
1165 return transient ? vk::ImageLayout::eShaderReadOnlyOptimal : layout;
1166 };
1167 const auto src_restore = settled_layout(src);
1168 const auto dst_restore = settled_layout(dst);
1169
1170 auto record_command = [&](vk::CommandBuffer cmd) {
1171 const auto transition = [&cmd](
1172 const std::shared_ptr<VKImage>& image,
1173 vk::ImageLayout from,
1174 vk::ImageLayout to,
1175 vk::AccessFlags src_access,
1176 vk::AccessFlags dst_access,
1177 vk::PipelineStageFlags src_stage,
1178 vk::PipelineStageFlags dst_stage) {
1179 vk::ImageMemoryBarrier barrier {};
1180 barrier.oldLayout = from;
1181 barrier.newLayout = to;
1182 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1183 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1184 barrier.image = image->get_image();
1185 barrier.subresourceRange = {
1186 image->get_aspect_flags(), 0,
1187 image->get_mip_levels(), 0,
1188 image->get_array_layers()
1189 };
1190 barrier.srcAccessMask = src_access;
1191 barrier.dstAccessMask = dst_access;
1192 cmd.pipelineBarrier(src_stage, dst_stage, vk::DependencyFlags {}, {}, {}, barrier);
1193 };
1194
1195 constexpr auto any_access = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite;
1196
1197 transition(src, src->get_current_layout(), vk::ImageLayout::eTransferSrcOptimal,
1198 any_access, vk::AccessFlagBits::eTransferRead,
1199 vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer);
1200 transition(dst, dst->get_current_layout(), vk::ImageLayout::eTransferDstOptimal,
1201 any_access, vk::AccessFlagBits::eTransferWrite,
1202 vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer);
1203
1204 cmd.blitImage(
1205 src->get_image(), vk::ImageLayout::eTransferSrcOptimal,
1206 dst->get_image(), vk::ImageLayout::eTransferDstOptimal,
1207 1, &region, filter);
1208
1209 transition(src, vk::ImageLayout::eTransferSrcOptimal, src_restore,
1210 vk::AccessFlagBits::eTransferRead, any_access,
1211 vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eAllCommands);
1212 transition(dst, vk::ImageLayout::eTransferDstOptimal, dst_restore,
1213 vk::AccessFlagBits::eTransferWrite, any_access,
1214 vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eAllCommands);
1215 };
1216
1217 if (deferred) {
1218 record_deferred_commands(record_command);
1219 } else {
1220 execute_immediate_commands(record_command);
1221 }
1222
1223 src->set_current_layout(src_restore);
1224 dst->set_current_layout(dst_restore);
1225
1226 return true;
1227}
#define MF_ERROR(comp, ctx,...)
vk::CommandBuffer cmd
IO::ImageData image
Definition Decoder.cpp:47
uint32_t * dst
const uint32_t * src
void execute_immediate_commands(const std::function< void(vk::CommandBuffer)> &recorder)
Execute immediate command recording for buffer operations.
bool supports_blit(vk::Format src_format, vk::Format dst_format, vk::Filter filter=vk::Filter::eNearest) const
Whether a blit between two formats is supported with a filter.
void record_deferred_commands(const std::function< void(vk::CommandBuffer)> &recorder)
Record deferred command recording for buffer operations.
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.

References cmd, MayaFlux::Journal::Core, dst, execute_immediate_commands(), MayaFlux::Journal::GraphicsBackend, image, MF_ERROR, record_deferred_commands(), src, and supports_blit().

Referenced by MayaFlux::Portal::Graphics::TextureLoom::blit_layer().

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