Upload image data using a caller-supplied persistent staging buffer.
711{
712 if (!
image || !data || !staging) {
714 "Invalid parameters for upload_image_data_with_staging");
715 return;
716 }
717
718 void* mapped = staging->get_mapped_ptr();
719 if (!mapped) {
721 "upload_image_data_with_staging: staging buffer has no mapped pointer");
722 return;
723 }
724
725 std::memcpy(mapped, data,
size);
726 staging->mark_dirty_range(0,
size);
727
728 auto& resources = staging->get_buffer_resources();
729 vk::MappedMemoryRange
range { resources.memory, 0, VK_WHOLE_SIZE };
730
732 result != vk::Result::eSuccess) {
734 "upload_image_data_with_staging: flush failed: {}", vk::to_string(result));
735 }
736
738 vk::ImageMemoryBarrier barrier {};
739 barrier.oldLayout =
image->get_current_layout();
740 barrier.newLayout = vk::ImageLayout::eTransferDstOptimal;
741 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
742 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
743 barrier.image =
image->get_image();
744 barrier.subresourceRange = {
745 image->get_aspect_flags(), 0,
746 image->get_mip_levels(), 0,
747 image->get_array_layers()
748 };
749 barrier.srcAccessMask = vk::AccessFlagBits::eShaderRead;
750 barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
751
753 vk::PipelineStageFlagBits::eFragmentShader,
754 vk::PipelineStageFlagBits::eTransfer,
755 {}, 0, nullptr, 0, nullptr, 1, &barrier);
756
757 vk::BufferImageCopy region {};
758 region.imageSubresource.aspectMask =
image->get_aspect_flags();
759 region.imageSubresource.layerCount =
image->get_array_layers();
760 region.imageOffset = vk::Offset3D { 0, 0, 0 };
761 region.imageExtent = vk::Extent3D {
765 };
766
767 cmd.copyBufferToImage(
768 staging->get_buffer(),
770 vk::ImageLayout::eTransferDstOptimal,
771 1, ®ion);
772
773 barrier.oldLayout = vk::ImageLayout::eTransferDstOptimal;
774 barrier.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
775 barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
776 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
777
779 vk::PipelineStageFlagBits::eTransfer,
780 vk::PipelineStageFlagBits::eFragmentShader,
781 {}, 0, nullptr, 0, nullptr, 1, &barrier);
782 });
783
784 image->set_current_layout(vk::ImageLayout::eShaderReadOnlyOptimal);
785
787 "upload_image_data_with_staging: {} bytes to image {}x{}",
789}
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void execute_immediate_commands(const std::function< void(vk::CommandBuffer)> &recorder)
Execute immediate command recording for buffer operations.
vk::Device get_device() const
Get logical device.
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.
std::vector< double > range(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Value range (max - min) per window.