vkQuake2 doxygen  1.0 dev
vk_buffer.c File Reference
#include "vk_local.h"

Go to the source code of this file.

Functions

static void copyBuffer (const VkBuffer *src, VkBuffer *dst, VkDeviceSize size)
 
static void createStagedBuffer (const void *data, VkDeviceSize size, qvkbuffer_t *dstBuffer, qvkbufferopts_t bufferOpts, qvkbuffer_t *stagingBuffer)
 
VkResult QVk_CreateBuffer (VkDeviceSize size, qvkbuffer_t *dstBuffer, const qvkbufferopts_t options)
 
void QVk_FreeBuffer (qvkbuffer_t *buffer)
 
VkResult QVk_CreateStagingBuffer (VkDeviceSize size, qvkbuffer_t *dstBuffer, VkMemoryPropertyFlags reqMemFlags, VkMemoryPropertyFlags prefMemFlags)
 
VkResult QVk_CreateUniformBuffer (VkDeviceSize size, qvkbuffer_t *dstBuffer, VkMemoryPropertyFlags reqMemFlags, VkMemoryPropertyFlags prefMemFlags)
 
void QVk_CreateVertexBuffer (const void *data, VkDeviceSize size, qvkbuffer_t *dstBuffer, qvkbuffer_t *stagingBuffer, VkMemoryPropertyFlags reqMemFlags, VkMemoryPropertyFlags prefMemFlags)
 
void QVk_CreateIndexBuffer (const void *data, VkDeviceSize size, qvkbuffer_t *dstBuffer, qvkbuffer_t *stagingBuffer, VkMemoryPropertyFlags reqMemFlags, VkMemoryPropertyFlags prefMemFlags)
 

Function Documentation

◆ copyBuffer()

static void copyBuffer ( const VkBuffer *  src,
VkBuffer *  dst,
VkDeviceSize  size 
)
static

Definition at line 24 of file vk_buffer.c.

25 {
26  VkCommandBuffer commandBuffer = QVk_CreateCommandBuffer(&vk_transferCommandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
27  QVk_BeginCommand(&commandBuffer);
28 
29  VkBufferCopy copyRegion = {
30  .srcOffset = 0,
31  .dstOffset = 0,
32  .size = size
33  };
34  vkCmdCopyBuffer(commandBuffer, *src, *dst, 1, &copyRegion);
35 
36  QVk_SubmitCommand(&commandBuffer, &vk_device.transferQueue);
37  vkFreeCommandBuffers(vk_device.logical, vk_transferCommandPool, 1, &commandBuffer);
38 }

Referenced by createStagedBuffer().

◆ createStagedBuffer()

static void createStagedBuffer ( const void data,
VkDeviceSize  size,
qvkbuffer_t dstBuffer,
qvkbufferopts_t  bufferOpts,
qvkbuffer_t stagingBuffer 
)
static

Definition at line 41 of file vk_buffer.c.

42 {
43  qvkbuffer_t *stgBuffer = stagingBuffer;
44  // create/release internal staging buffer if NULL has been passed
45  if (!stagingBuffer)
46  {
47  stgBuffer = (qvkbuffer_t *)malloc(sizeof(qvkbuffer_t));
48  VK_VERIFY(QVk_CreateStagingBuffer(size, stgBuffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT));
49  }
50 
51  if (data)
52  {
53  void *dst;
54  // staging buffers in vkQuake2 are required to be host coherent, so no flushing/invalidation is involved
55  VK_VERIFY(vmaMapMemory(vk_malloc, stgBuffer->allocation, &dst));
56  memcpy(dst, data, (size_t)size);
57  vmaUnmapMemory(vk_malloc, stgBuffer->allocation);
58  }
59 
60  VK_VERIFY(QVk_CreateBuffer(size, dstBuffer, bufferOpts));
61  copyBuffer(&stgBuffer->buffer, &dstBuffer->buffer, size);
62 
63  if (!stagingBuffer)
64  {
65  QVk_FreeBuffer(stgBuffer);
66  free(stgBuffer);
67  }
68 }

Referenced by QVk_CreateIndexBuffer(), and QVk_CreateVertexBuffer().

◆ QVk_CreateBuffer()

VkResult QVk_CreateBuffer ( VkDeviceSize  size,
qvkbuffer_t dstBuffer,
const qvkbufferopts_t  options 
)

Definition at line 70 of file vk_buffer.c.

71 {
72  VkBufferCreateInfo bcInfo = {
73  .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
74  .pNext = NULL,
75  .flags = 0,
76  .size = size,
77  .usage = options.usage,
78  .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
79  .queueFamilyIndexCount = 0,
80  .pQueueFamilyIndices = NULL,
81  };
82 
83  // separate transfer queue makes sense only if the buffer is targetted for being transfered to GPU, so ignore it if it's CPU-only
84  uint32_t queueFamilies[] = { (uint32_t)vk_device.gfxFamilyIndex, (uint32_t)vk_device.transferFamilyIndex };
86  {
87  bcInfo.sharingMode = VK_SHARING_MODE_CONCURRENT;
88  bcInfo.queueFamilyIndexCount = 2;
89  bcInfo.pQueueFamilyIndices = queueFamilies;
90  }
91 
92  VmaAllocationCreateInfo vmallocInfo = {
93  .flags = options.vmaFlags,
94  .usage = options.vmaUsage,
95  .requiredFlags = options.reqMemFlags,
96  .preferredFlags = options.prefMemFlags,
97  .memoryTypeBits = 0,
98  .pool = VK_NULL_HANDLE,
99  .pUserData = NULL
100  };
101 
102  dstBuffer->currentOffset = 0;
103  return vmaCreateBuffer(vk_malloc, &bcInfo, &vmallocInfo, &dstBuffer->buffer, &dstBuffer->allocation, &dstBuffer->allocInfo);
104 }

Referenced by createStagedBuffer(), QVk_CreateStagingBuffer(), QVk_CreateUniformBuffer(), and QVk_ReadPixels().

◆ QVk_CreateIndexBuffer()

void QVk_CreateIndexBuffer ( const void data,
VkDeviceSize  size,
qvkbuffer_t dstBuffer,
qvkbuffer_t stagingBuffer,
VkMemoryPropertyFlags  reqMemFlags,
VkMemoryPropertyFlags  prefMemFlags 
)

Definition at line 158 of file vk_buffer.c.

159 {
160  qvkbufferopts_t dstOpts = {
161  .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
162  .reqMemFlags = reqMemFlags,
163  .prefMemFlags = prefMemFlags,
164  .vmaUsage = VMA_MEMORY_USAGE_GPU_ONLY,
165  .vmaFlags = 0
166  };
167 
168  createStagedBuffer(data, size, dstBuffer, dstOpts, stagingBuffer);
169 }

Referenced by CreateDynamicBuffers(), CreateStaticBuffers(), and QVk_GetIndexBuffer().

◆ QVk_CreateStagingBuffer()

VkResult QVk_CreateStagingBuffer ( VkDeviceSize  size,
qvkbuffer_t dstBuffer,
VkMemoryPropertyFlags  reqMemFlags,
VkMemoryPropertyFlags  prefMemFlags 
)

Definition at line 114 of file vk_buffer.c.

115 {
116  qvkbufferopts_t stagingOpts = {
117  .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
118  .reqMemFlags = reqMemFlags,
119  .prefMemFlags = prefMemFlags,
120  .vmaUsage = VMA_MEMORY_USAGE_CPU_ONLY,
121  .vmaFlags = 0
122  };
123 
124  return QVk_CreateBuffer(size, dstBuffer, stagingOpts);
125 }

Referenced by createStagedBuffer(), and CreateStagingBuffers().

◆ QVk_CreateUniformBuffer()

VkResult QVk_CreateUniformBuffer ( VkDeviceSize  size,
qvkbuffer_t dstBuffer,
VkMemoryPropertyFlags  reqMemFlags,
VkMemoryPropertyFlags  prefMemFlags 
)

Definition at line 127 of file vk_buffer.c.

128 {
129  qvkbufferopts_t dstOpts = {
130  .usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
131  .reqMemFlags = reqMemFlags,
132  .prefMemFlags = prefMemFlags,
133  .vmaUsage = VMA_MEMORY_USAGE_CPU_TO_GPU,
134  // When resizing dynamic uniform buffers on Intel, the Linux driver may throw a warning:
135  // "Mapping an image with layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used."
136  // Minor annoyance but we don't want any validation warnings, so we create dedicated allocation for uniform buffer.
137  // more details: https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/issues/34
138  // Note that this is a false positive which in other cases could be ignored: https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/general_considerations.html#general_considerations_validation_layer_warnings
140  };
141 
142  return QVk_CreateBuffer(size, dstBuffer, dstOpts);
143 }

Referenced by CreateDynamicBuffers(), and QVk_GetUniformBuffer().

◆ QVk_CreateVertexBuffer()

void QVk_CreateVertexBuffer ( const void data,
VkDeviceSize  size,
qvkbuffer_t dstBuffer,
qvkbuffer_t stagingBuffer,
VkMemoryPropertyFlags  reqMemFlags,
VkMemoryPropertyFlags  prefMemFlags 
)

Definition at line 145 of file vk_buffer.c.

146 {
147  qvkbufferopts_t dstOpts = {
148  .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
149  .reqMemFlags = reqMemFlags,
150  .prefMemFlags = prefMemFlags,
151  .vmaUsage = VMA_MEMORY_USAGE_GPU_ONLY,
152  .vmaFlags = 0
153  };
154 
155  createStagedBuffer(data, size, dstBuffer, dstOpts, stagingBuffer);
156 }

Referenced by CreateDynamicBuffers(), CreateStaticBuffers(), and QVk_GetVertexBuffer().

◆ QVk_FreeBuffer()

void QVk_FreeBuffer ( qvkbuffer_t buffer)

Definition at line 106 of file vk_buffer.c.

107 {
108  vmaDestroyBuffer(vk_malloc, buffer->buffer, buffer->allocation);
109  buffer->buffer = VK_NULL_HANDLE;
110  buffer->allocation = VK_NULL_HANDLE;
111  buffer->currentOffset = 0;
112 }

Referenced by createStagedBuffer(), QVk_ReadPixels(), QVk_Shutdown(), and ReleaseSwapBuffers().

QVk_FreeBuffer
void QVk_FreeBuffer(qvkbuffer_t *buffer)
Definition: vk_buffer.c:106
createStagedBuffer
static void createStagedBuffer(const void *data, VkDeviceSize size, qvkbuffer_t *dstBuffer, qvkbufferopts_t bufferOpts, qvkbuffer_t *stagingBuffer)
Definition: vk_buffer.c:41
qvkdevice_t::logical
VkDevice logical
Definition: qvk.h:40
qvkbuffer_t::buffer
VkBuffer buffer
Definition: qvk.h:126
QVk_CreateBuffer
VkResult QVk_CreateBuffer(VkDeviceSize size, qvkbuffer_t *dstBuffer, const qvkbufferopts_t options)
Definition: vk_buffer.c:70
vmaUnmapMemory
void vmaUnmapMemory(VmaAllocator allocator, VmaAllocation allocation)
Unmaps memory represented by given allocation, mapped previously using vmaMapMemory().
buffer
GLenum GLfloat * buffer
Definition: qgl_win.c:151
qvkdevice_t::gfxFamilyIndex
int gfxFamilyIndex
Definition: qvk.h:46
vk_device
qvkdevice_t vk_device
Definition: vk_common.c:51
qvkbufferopts_t::prefMemFlags
VkMemoryPropertyFlags prefMemFlags
Definition: qvk.h:146
vk_transferCommandPool
VkCommandPool vk_transferCommandPool
Definition: vk_common.c:96
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
@ VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT
Set this flag if the allocation should have its own memory block.
Definition: vk_mem_alloc.h:2114
VMA_MEMORY_USAGE_CPU_ONLY
@ VMA_MEMORY_USAGE_CPU_ONLY
Memory will be mappable on host.
Definition: vk_mem_alloc.h:2086
qvkbufferopts_t
Definition: qvk.h:142
qvkbuffer_t
Definition: qvk.h:124
VMA_MEMORY_USAGE_GPU_ONLY
@ VMA_MEMORY_USAGE_GPU_ONLY
Memory will be used on device only, so fast access from the device is preferred.
Definition: vk_mem_alloc.h:2076
qvkbuffer_t::currentOffset
VkDeviceSize currentOffset
Definition: qvk.h:129
QVk_SubmitCommand
void QVk_SubmitCommand(const VkCommandBuffer *commandBuffer, const VkQueue *queue)
Definition: vk_cmd.c:35
NULL
#define NULL
Definition: q_shared.h:67
qvkbuffer_t::allocation
VmaAllocation allocation
Definition: qvk.h:127
QVk_BeginCommand
VkResult QVk_BeginCommand(const VkCommandBuffer *commandBuffer)
Definition: vk_cmd.c:23
qvkbuffer_t::allocInfo
VmaAllocationInfo allocInfo
Definition: qvk.h:128
QVk_CreateCommandBuffer
VkCommandBuffer QVk_CreateCommandBuffer(const VkCommandPool *commandPool, VkCommandBufferLevel level)
Definition: vk_cmd.c:78
VK_VERIFY
#define VK_VERIFY(x)
Definition: vk_local.h:59
QVk_CreateStagingBuffer
VkResult QVk_CreateStagingBuffer(VkDeviceSize size, qvkbuffer_t *dstBuffer, VkMemoryPropertyFlags reqMemFlags, VkMemoryPropertyFlags prefMemFlags)
Definition: vk_buffer.c:114
vmaMapMemory
VkResult vmaMapMemory(VmaAllocator allocator, VmaAllocation allocation, void **ppData)
Maps memory represented by given allocation and returns pointer to it.
copyBuffer
static void copyBuffer(const VkBuffer *src, VkBuffer *dst, VkDeviceSize size)
Definition: vk_buffer.c:24
vk_malloc
VmaAllocator vk_malloc
Definition: vk_common.c:48
VMA_MEMORY_USAGE_CPU_TO_GPU
@ VMA_MEMORY_USAGE_CPU_TO_GPU
Memory that is both mappable on host (guarantees to be HOST_VISIBLE) and preferably fast to access by...
Definition: vk_mem_alloc.h:2093
qvkbufferopts_t::usage
VkBufferUsageFlags usage
Definition: qvk.h:144
vmaCreateBuffer
VkResult vmaCreateBuffer(VmaAllocator allocator, const VkBufferCreateInfo *pBufferCreateInfo, const VmaAllocationCreateInfo *pAllocationCreateInfo, VkBuffer *pBuffer, VmaAllocation *pAllocation, VmaAllocationInfo *pAllocationInfo)
qvkbufferopts_t::vmaUsage
VmaMemoryUsage vmaUsage
Definition: qvk.h:147
qvkdevice_t::transferQueue
VkQueue transferQueue
Definition: qvk.h:45
vmaDestroyBuffer
void vmaDestroyBuffer(VmaAllocator allocator, VkBuffer buffer, VmaAllocation allocation)
Destroys Vulkan buffer and frees allocated memory.
qvkdevice_t::transferFamilyIndex
int transferFamilyIndex
Definition: qvk.h:48
qvkbufferopts_t::vmaFlags
VmaAllocationCreateFlags vmaFlags
Definition: qvk.h:148
qvkbufferopts_t::reqMemFlags
VkMemoryPropertyFlags reqMemFlags
Definition: qvk.h:145
VmaAllocationCreateInfo::flags
VmaAllocationCreateFlags flags
Use VmaAllocationCreateFlagBits enum.
Definition: vk_mem_alloc.h:2217
VmaAllocationCreateInfo
Definition: vk_mem_alloc.h:2214