VapourSynth-llvmexpr
Loading...
Searching...
No Matches
vkexpr::VulkanMemory Class Reference

#include <llvmexpr/runtime/vulkan/VulkanMemory.hpp>

Public Member Functions

 VulkanMemory (VulkanContext &ctx)
 ~VulkanMemory ()
 VulkanMemory (const VulkanMemory &)=delete
VulkanMemoryoperator= (const VulkanMemory &)=delete
 VulkanMemory (VulkanMemory &&)=delete
VulkanMemoryoperator= (VulkanMemory &&)=delete
VulkanBuffer createGPUBuffer (VkDeviceSize size, VkBufferUsageFlags usage=VK_BUFFER_USAGE_STORAGE_BUFFER_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
VulkanBuffer createStagingBuffer (VkDeviceSize size, bool for_upload=true)
void destroyBuffer (VulkanBuffer &buffer)
void uploadToBuffer (VulkanBuffer &gpu_buffer, const void *data, VkDeviceSize size, VkDeviceSize offset=0)
void downloadFromBuffer (VulkanBuffer &gpu_buffer, void *data, VkDeviceSize size, VkDeviceSize offset=0)
void copyBuffer (VulkanBuffer &src, VulkanBuffer &dst, VkDeviceSize size)
VmaAllocator getAllocator () const
void flushBuffer (const VulkanBuffer &buffer, VkDeviceSize size, VkDeviceSize offset=0) const
void invalidateBuffer (const VulkanBuffer &buffer, VkDeviceSize size, VkDeviceSize offset=0) const

Detailed Description

Definition at line 80 of file VulkanMemory.hpp.

Constructor & Destructor Documentation

◆ VulkanMemory() [1/3]

vkexpr::VulkanMemory::VulkanMemory ( VulkanContext & ctx)
explicit

Definition at line 39 of file VulkanMemory.cpp.

39 : context(ctx) {
40 VmaVulkanFunctions vulkan_functions = {};
41 vulkan_functions.vkGetInstanceProcAddr = vkGetInstanceProcAddr;
42 vulkan_functions.vkGetDeviceProcAddr = vkGetDeviceProcAddr;
43
44 VmaAllocatorCreateInfo allocator_info = {};
45 allocator_info.vulkanApiVersion = VK_API_VERSION_1_3;
46 allocator_info.physicalDevice = *context.getPhysicalDevice();
47 allocator_info.device = *context.getDevice();
48 allocator_info.instance = *context.getInstanceRef();
49 allocator_info.pVulkanFunctions = &vulkan_functions;
50
51 if (vmaCreateAllocator(&allocator_info, &allocator) != VK_SUCCESS) {
52 throw std::runtime_error("Failed to create VMA allocator");
53 }
54
55 vk::CommandPoolCreateInfo pool_info(
56 vk::CommandPoolCreateFlagBits::eResetCommandBuffer,
57 context.getQueueFamilyIndex());
58 transfer_pool = vk::raii::CommandPool(context.getDevice(), pool_info);
59
60 vk::CommandBufferAllocateInfo cmd_info(*transfer_pool,
61 vk::CommandBufferLevel::ePrimary, 1);
62 auto cmd_buffers = vk::raii::CommandBuffers(context.getDevice(), cmd_info);
63 transfer_cmd = std::move(cmd_buffers[0]);
64
65 vk::FenceCreateInfo fence_info;
66 transfer_fence = vk::raii::Fence(context.getDevice(), fence_info);
67}

Referenced by operator=(), operator=(), VulkanMemory(), and VulkanMemory().

◆ ~VulkanMemory()

vkexpr::VulkanMemory::~VulkanMemory ( )

Definition at line 69 of file VulkanMemory.cpp.

69 {
70 if (allocator != VK_NULL_HANDLE) {
71 vmaDestroyAllocator(allocator);
72 }
73}

◆ VulkanMemory() [2/3]

vkexpr::VulkanMemory::VulkanMemory ( const VulkanMemory & )
delete

References VulkanMemory().

◆ VulkanMemory() [3/3]

vkexpr::VulkanMemory::VulkanMemory ( VulkanMemory && )
delete

References VulkanMemory().

Member Function Documentation

◆ copyBuffer()

void vkexpr::VulkanMemory::copyBuffer ( VulkanBuffer & src,
VulkanBuffer & dst,
VkDeviceSize size )

Definition at line 195 of file VulkanMemory.cpp.

196 {
197 vk::CommandBufferBeginInfo begin_info(
198 vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
199 transfer_cmd.begin(begin_info);
200
201 vk::BufferCopy copy_region(0, 0, size);
202 transfer_cmd.copyBuffer(src.buffer, dst.buffer, copy_region);
203
204 transfer_cmd.end();
205
206 vk::SubmitInfo submit_info;
207 submit_info.setCommandBuffers(*transfer_cmd);
208 context.submit(submit_info, *transfer_fence);
209
210 auto result =
211 context.getDevice().waitForFences(*transfer_fence, VK_TRUE, UINT64_MAX);
212 if (result != vk::Result::eSuccess) {
213 throw std::runtime_error("Failed to wait for copy fence");
214 }
215 context.getDevice().resetFences(*transfer_fence);
216}

References vkexpr::VulkanBuffer::buffer.

◆ createGPUBuffer()

VulkanBuffer vkexpr::VulkanMemory::createGPUBuffer ( VkDeviceSize size,
VkBufferUsageFlags usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT )

Definition at line 75 of file VulkanMemory.cpp.

76 {
77 VkBufferCreateInfo buffer_info = {};
78 buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
79 buffer_info.size = size;
80 buffer_info.usage = usage;
81 buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
82
83 VmaAllocationCreateInfo alloc_info = {};
84 alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
85
86 VkBuffer buffer = VK_NULL_HANDLE;
87 VmaAllocation allocation = VK_NULL_HANDLE;
88 VmaAllocationInfo allocation_info = {};
89
90 if (vmaCreateBuffer(allocator, &buffer_info, &alloc_info, &buffer,
91 &allocation, &allocation_info) != VK_SUCCESS) {
92 throw std::runtime_error("Failed to create GPU buffer");
93 }
94
95 return {buffer, allocation, allocation_info, size};
96}

References vkexpr::VulkanBuffer::size.

◆ createStagingBuffer()

VulkanBuffer vkexpr::VulkanMemory::createStagingBuffer ( VkDeviceSize size,
bool for_upload = true )

Definition at line 98 of file VulkanMemory.cpp.

99 {
100 VkBufferCreateInfo buffer_info = {};
101 buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
102 buffer_info.size = size;
103 buffer_info.usage = for_upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT
104 : VK_BUFFER_USAGE_TRANSFER_DST_BIT;
105 buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
106
107 VmaAllocationCreateInfo alloc_info = {};
108 alloc_info.usage = VMA_MEMORY_USAGE_AUTO;
109 alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
110 VMA_ALLOCATION_CREATE_MAPPED_BIT;
111 if (!for_upload) {
112 alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT |
113 VMA_ALLOCATION_CREATE_MAPPED_BIT;
114 }
115
116 VkBuffer buffer = VK_NULL_HANDLE;
117 VmaAllocation allocation = VK_NULL_HANDLE;
118 VmaAllocationInfo allocation_info = {};
119
120 if (vmaCreateBuffer(allocator, &buffer_info, &alloc_info, &buffer,
121 &allocation, &allocation_info) != VK_SUCCESS) {
122 throw std::runtime_error("Failed to create staging buffer");
123 }
124
125 return {buffer, allocation, allocation_info, size};
126}

References vkexpr::VulkanBuffer::size.

Referenced by downloadFromBuffer(), and uploadToBuffer().

◆ destroyBuffer()

void vkexpr::VulkanMemory::destroyBuffer ( VulkanBuffer & buffer)

Definition at line 128 of file VulkanMemory.cpp.

128 {
129 if (buffer.isValid()) {
130 vmaDestroyBuffer(allocator, buffer.buffer, buffer.allocation);
131 buffer.buffer = VK_NULL_HANDLE;
132 buffer.allocation = VK_NULL_HANDLE;
133 buffer.size = 0;
134 }
135}

References vkexpr::VulkanBuffer::allocation, vkexpr::VulkanBuffer::buffer, vkexpr::VulkanBuffer::isValid(), and vkexpr::VulkanBuffer::size.

Referenced by downloadFromBuffer(), and uploadToBuffer().

◆ downloadFromBuffer()

void vkexpr::VulkanMemory::downloadFromBuffer ( VulkanBuffer & gpu_buffer,
void * data,
VkDeviceSize size,
VkDeviceSize offset = 0 )

Definition at line 166 of file VulkanMemory.cpp.

167 {
168 auto staging = createStagingBuffer(size, false);
169
170 vk::CommandBufferBeginInfo begin_info(
171 vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
172 transfer_cmd.begin(begin_info);
173
174 vk::BufferCopy copy_region(offset, 0, size);
175 transfer_cmd.copyBuffer(gpu_buffer.buffer, staging.buffer, copy_region);
176
177 transfer_cmd.end();
178
179 vk::SubmitInfo submit_info;
180 submit_info.setCommandBuffers(*transfer_cmd);
181 context.submit(submit_info, *transfer_fence);
182
183 auto result =
184 context.getDevice().waitForFences(*transfer_fence, VK_TRUE, UINT64_MAX);
185 if (result != vk::Result::eSuccess) {
186 throw std::runtime_error("Failed to wait for download fence");
187 }
188 context.getDevice().resetFences(*transfer_fence);
189
190 std::memcpy(data, staging.getMappedData(), size);
191
192 destroyBuffer(staging);
193}
VulkanBuffer createStagingBuffer(VkDeviceSize size, bool for_upload=true)
void destroyBuffer(VulkanBuffer &buffer)

References vkexpr::VulkanBuffer::buffer, createStagingBuffer(), and destroyBuffer().

◆ flushBuffer()

void vkexpr::VulkanMemory::flushBuffer ( const VulkanBuffer & buffer,
VkDeviceSize size,
VkDeviceSize offset = 0 ) const

Definition at line 218 of file VulkanMemory.cpp.

219 {
220 if (allocator == VK_NULL_HANDLE || buffer.allocation == VK_NULL_HANDLE ||
221 buffer.getMappedData() == nullptr || size == 0) {
222 return;
223 }
224 (void)vmaFlushAllocation(allocator, buffer.allocation, offset, size);
225}

References vkexpr::VulkanBuffer::allocation, and vkexpr::VulkanBuffer::getMappedData().

◆ getAllocator()

VmaAllocator vkexpr::VulkanMemory::getAllocator ( ) const
inlinenodiscard

Definition at line 108 of file VulkanMemory.hpp.

108{ return allocator; }

◆ invalidateBuffer()

void vkexpr::VulkanMemory::invalidateBuffer ( const VulkanBuffer & buffer,
VkDeviceSize size,
VkDeviceSize offset = 0 ) const

Definition at line 227 of file VulkanMemory.cpp.

229 {
230 if (allocator == VK_NULL_HANDLE || buffer.allocation == VK_NULL_HANDLE ||
231 buffer.getMappedData() == nullptr || size == 0) {
232 return;
233 }
234 (void)vmaInvalidateAllocation(allocator, buffer.allocation, offset, size);
235}

References vkexpr::VulkanBuffer::allocation, and vkexpr::VulkanBuffer::getMappedData().

◆ operator=() [1/2]

VulkanMemory & vkexpr::VulkanMemory::operator= ( const VulkanMemory & )
delete

References VulkanMemory().

◆ operator=() [2/2]

VulkanMemory & vkexpr::VulkanMemory::operator= ( VulkanMemory && )
delete

References VulkanMemory().

◆ uploadToBuffer()

void vkexpr::VulkanMemory::uploadToBuffer ( VulkanBuffer & gpu_buffer,
const void * data,
VkDeviceSize size,
VkDeviceSize offset = 0 )

Definition at line 137 of file VulkanMemory.cpp.

138 {
139 auto staging = createStagingBuffer(size, true);
140
141 std::memcpy(staging.getMappedData(), data, size);
142
143 vk::CommandBufferBeginInfo begin_info(
144 vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
145 transfer_cmd.begin(begin_info);
146
147 vk::BufferCopy copy_region(0, offset, size);
148 transfer_cmd.copyBuffer(staging.buffer, gpu_buffer.buffer, copy_region);
149
150 transfer_cmd.end();
151
152 vk::SubmitInfo submit_info;
153 submit_info.setCommandBuffers(*transfer_cmd);
154 context.submit(submit_info, *transfer_fence);
155
156 auto result =
157 context.getDevice().waitForFences(*transfer_fence, VK_TRUE, UINT64_MAX);
158 if (result != vk::Result::eSuccess) {
159 throw std::runtime_error("Failed to wait for upload fence");
160 }
161 context.getDevice().resetFences(*transfer_fence);
162
163 destroyBuffer(staging);
164}

References vkexpr::VulkanBuffer::buffer, createStagingBuffer(), and destroyBuffer().


The documentation for this class was generated from the following files: