27{
28 buffer_service->initialize_buffer = [this](const std::shared_ptr<void>& vk_buf) -> void {
29 auto buffer = std::static_pointer_cast<Buffers::VKBuffer>(vk_buf);
31 };
32
33 buffer_service->allocate_raw_buffer = [this](
34 size_t size_bytes,
35 uint32_t usage_flags,
36 uint32_t memory_property_flags,
37 bool host_visible,
38 void*& out_buffer,
39 void*& out_memory,
40 void*& out_mapped_ptr) -> void {
41 vk::Buffer buf;
42 vk::DeviceMemory mem;
43 void* mapped = nullptr;
45 size_bytes,
46 vk::BufferUsageFlags(usage_flags),
47 vk::MemoryPropertyFlags(memory_property_flags),
48 host_visible,
49 buf, mem, mapped);
50 out_buffer = static_cast<VkBuffer>(buf);
51 out_memory = static_cast<VkDeviceMemory>(mem);
52 out_mapped_ptr = mapped;
53 };
54
55 buffer_service->destroy_buffer = [this](const std::shared_ptr<void>& vk_buf) {
56 auto buffer = std::static_pointer_cast<Buffers::VKBuffer>(vk_buf);
58 };
59
60 buffer_service->get_buffer_device_address = [this](const std::shared_ptr<void>& vk_buf) -> uint64_t {
61 auto buffer = std::static_pointer_cast<Buffers::VKBuffer>(vk_buf);
63 return static_cast<uint64_t>(address);
64 };
65
66 buffer_service->execute_immediate = [this](const std::function<void(void*)>& recorder) {
68 recorder(
static_cast<void*
>(
cmd));
69 });
70 };
71
72 buffer_service->record_deferred = [this](const std::function<void(void*)>& recorder) {
74 recorder(
static_cast<void*
>(
cmd));
75 });
76 };
77
78 buffer_service->flush_range = [
this](
void* memory,
size_t offset,
size_t size) {
79 vk::DeviceMemory mem(reinterpret_cast<VkDeviceMemory>(memory));
80 vk::MappedMemoryRange
range { mem,
offset, size == 0 ? VK_WHOLE_SIZE : size };
81 if (
auto result =
m_context.
get_device().flushMappedMemoryRanges(1, &range); result != vk::Result::eSuccess) {
83 "Failed to flush mapped memory range: {}", vk::to_string(result));
84 }
85 };
86
87 buffer_service->invalidate_range = [
this](
void* memory,
size_t offset,
size_t size) {
88 vk::DeviceMemory mem(reinterpret_cast<VkDeviceMemory>(memory));
89 vk::MappedMemoryRange
range { mem,
offset, size == 0 ? VK_WHOLE_SIZE : size };
90 if (
auto result =
m_context.
get_device().invalidateMappedMemoryRanges(1, &range); result != vk::Result::eSuccess) {
92 "Failed to invalidate mapped memory range: {}", vk::to_string(result));
93 }
94 };
95
96 buffer_service->map_buffer = [
this](
void* memory,
size_t offset,
size_t size) ->
void* {
97 vk::DeviceMemory mem(reinterpret_cast<VkDeviceMemory>(memory));
99 };
100
101 buffer_service->unmap_buffer = [this](void* memory) {
102 vk::DeviceMemory mem(reinterpret_cast<VkDeviceMemory>(memory));
104 };
105
106 buffer_service->copy_buffer = [this](void* src, void* dst, size_t size, size_t src_off, size_t dst_off) {
107 vk::Buffer s(static_cast<VkBuffer>(src));
108 vk::Buffer d(static_cast<VkBuffer>(dst));
110 vk::BufferCopy region { src_off, dst_off, size };
111 cmd.copyBuffer(s, d, 1, ®ion);
112 });
113 };
114
115 buffer_service->execute_fenced = [this](const std::function<void(void*)>& recorder)
116 -> std::shared_ptr<void> {
118
119 recorder(
static_cast<void*
>(
cmd));
120
122
124 vk::FenceCreateInfo fence_info {};
125 vk::Fence
fence = device.createFence(fence_info);
126
127 vk::SubmitInfo submit_info {};
128 submit_info.commandBufferCount = 1;
129 submit_info.pCommandBuffers = &
cmd;
130
132 result != vk::Result::eSuccess) {
134 "execute_fenced: queue submit failed: {}", vk::to_string(result));
135 device.destroyFence(
fence);
137 return nullptr;
138 }
139
140 auto handle = std::make_shared<FencedSubmission>();
142 handle->fence =
fence;
143 return handle;
144 };
145
146 buffer_service->wait_fenced = [this](const std::shared_ptr<void>& handle) {
147 if (!handle)
148 return;
149 auto sub = std::static_pointer_cast<FencedSubmission>(handle);
150 if (!sub->fence)
151 return;
152
154 if (auto result = device.waitForFences(1, &sub->fence, VK_TRUE, UINT64_MAX);
155 result != vk::Result::eSuccess) {
157 "wait_fenced: waitForFences failed: {}", vk::to_string(result));
158 }
159 };
160
161 buffer_service->release_fenced = [this](const std::shared_ptr<void>& handle) {
162 if (!handle)
163 return;
164 auto sub = std::static_pointer_cast<FencedSubmission>(handle);
165
167 if (sub->fence) {
168 device.destroyFence(sub->fence);
169 sub->fence = nullptr;
170 }
171 if (sub->cmd) {
173 sub->cmd = nullptr;
174 }
175 };
176
177 buffer_service->copy_buffer_fenced = [this, buffer_service](void* src, void* dst, size_t size, size_t src_off, size_t dst_off)
178 -> std::shared_ptr<void> {
179 vk::Buffer s(static_cast<VkBuffer>(src));
180 vk::Buffer d(static_cast<VkBuffer>(dst));
181 return buffer_service->execute_fenced([&](void* cmd_ptr) {
182 vk::CommandBuffer
cmd(
static_cast<VkCommandBuffer
>(cmd_ptr));
183 vk::BufferCopy region { src_off, dst_off, static_cast<vk::DeviceSize>(size) };
184 cmd.copyBuffer(s, d, 1, ®ion);
185 });
186 };
187}
#define MF_ERROR(comp, ctx,...)
void cleanup_buffer(const std::shared_ptr< Buffers::VKBuffer > &buffer)
Cleanup a buffer and release associated resources.
vk::DeviceAddress get_buffer_device_address(const std::shared_ptr< Buffers::VKBuffer > &buffer) const
Query the Vulkan device address of an initialized BDA-capable buffer.
void execute_immediate_commands(const std::function< void(vk::CommandBuffer)> &recorder)
Execute immediate command recording for buffer operations.
VKCommandManager & m_command_manager
void initialize_buffer(const std::shared_ptr< Buffers::VKBuffer > &buffer)
Initialize a buffer for use with the graphics backend.
void allocate_raw_buffer(size_t size_bytes, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags memory_properties, bool host_visible, vk::Buffer &out_buffer, vk::DeviceMemory &out_memory, void *&out_mapped_ptr)
Allocate a raw VkBuffer/VkDeviceMemory pair without an owning VKBuffer object.
void record_deferred_commands(const std::function< void(vk::CommandBuffer)> &recorder)
Record deferred command recording for buffer operations.
void free_command_buffer(vk::CommandBuffer command_buffer)
Free a command buffer back to the pool.
vk::CommandBuffer begin_single_time_commands()
Begin single-time command (for transfers, etc.)
vk::Device get_device() const
Get logical device.
vk::Queue get_graphics_queue() const
Get graphics queue.
@ 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.