6#include <vulkan/vulkan.h>
13#if !defined(HEADLESS) && !defined(COMPUTE_DEBUG)
15 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT | VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT;
18 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT;
31 buffer->create(size, usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
32 stagingBuffer->create(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
59 memcpy(mappedMemory, data, size);
69 VkBufferMemoryBarrier2 releaseBarrier{VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2};
70 releaseBarrier.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT;
71 releaseBarrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT;
72 releaseBarrier.dstAccessMask = VK_ACCESS_2_NONE;
73 releaseBarrier.dstStageMask = VK_PIPELINE_STAGE_2_NONE;
76 releaseBarrier.buffer =
buffer->getBuffer();
77 releaseBarrier.offset = offset;
78 releaseBarrier.size = size;
82 VkBufferMemoryBarrier2 acquireBarrier{VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2};
83 acquireBarrier.srcAccessMask = VK_ACCESS_2_NONE;
84 acquireBarrier.srcStageMask = VK_PIPELINE_STAGE_2_NONE;
85 acquireBarrier.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT;
89 acquireBarrier.buffer =
buffer->getBuffer();
90 acquireBarrier.offset = offset;
91 acquireBarrier.size = size;
99 copyObject.
size = size;
101 stagedBufferSyncObjects.
copyObject = copyObject;
103 return stagedBufferSyncObjects;
107 debugName_ = name + (index.has_value() ? std::to_string(index.value()) :
"");
108 buffer->setDebugName(name +
" buffer" + (index.has_value() ? std::to_string(index.value()) :
""));
109 stagingBuffer->setDebugName(name +
" staging" + (index.has_value() ? std::to_string(index.value()) :
""));
120 if (
buffer.has_value() &&
buffer->getBufferSize() >= requiredSize) {
126 VkDeviceSize currentSize =
buffer.has_value() ?
buffer->getBufferSize() : 0;
127 VkDeviceSize newSize = requiredSize;
130 if (currentSize > 0) {
131 VkDeviceSize doubledSize = currentSize * 2;
132 if (doubledSize > newSize) {
133 newSize = doubledSize;
139 constexpr VkDeviceSize MAX_BUFFER_SIZE = 512 * 1024 * 1024;
140 if (newSize > MAX_BUFFER_SIZE && requiredSize <= MAX_BUFFER_SIZE) {
141 newSize = MAX_BUFFER_SIZE;
149 std::move(
buffer.value()),
160 buffer->create(newSize, usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
161 stagingBuffer->create(newSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
182 if (it->framesRemaining == 0) {
183 it->deviceBuffer.destroy();
184 it->stagingBuffer.destroy();
187 it->framesRemaining--;
195 if (!
buffer.has_value()) {
198 return buffer->getBufferSize();
The application context is the core class which stores the basic openxr and vulkan objects.
uint32_t getVkTransferQueueFamilyIndex() const
gets the transfer queue family index
uint32_t getVkGraphicsQueueFamilyIndex() const
Gets the zero-based index of the vulkan draw queue family.
VulkanStagedBufferSyncObjects uploadPartial(const ApplicationContext *context, const void *data, VkDeviceSize size, VkDeviceSize offset)
Upload data to a specific offset in the buffer (for incremental updates)
bool usePersistentMapping_
VkDeviceSize getSize() const
Gets the current size of the device buffer.
std::vector< PendingDeletion > pendingDeletions
bool ensureSize(VkDeviceSize requiredSize, VkBufferUsageFlags usage)
Ensures the buffer is at least the required size. If resizing is needed, the old buffers are moved to...
static constexpr uint32_t DELETION_DELAY_FRAMES
std::optional< VulkanBuffer > stagingBuffer
std::optional< VulkanBuffer > buffer
void setDebugName(const std::string &name, std::optional< uint32_t > index=std::nullopt)
VulkanStagedBufferSyncObjects upload(const ApplicationContext *context, const void *data, VkDeviceSize size)
void processPendingDeletions()
Destroys all buffers that were pending deletion. Call this after all frames that might reference old ...
ApplicationContext * context_
void create(ApplicationContext *context, VkDeviceSize size, VkBufferUsageFlags usage, bool persistentMapping=false)
Creates the staged buffer with device and staging buffers.
Log category system implementation.
constexpr VkPipelineStageFlags2 STAGED_BUFFER_DST_STAGES
constexpr size_t MIN_BUFFER_SIZE
VkDeviceSize dstOffset
Offset in destination buffer (for partial uploads)
VkBuffer destinationBuffer
BufferCopyObject copyObject
VkBufferMemoryBarrier2 acquireBarrier
VkBufferMemoryBarrier2 releaseBarrier
Old buffers waiting to be deleted after all frames complete.