Skip to content

Commit 93c98f8

Browse files
committed
Staging buffer transfers
1 parent 5e38197 commit 93c98f8

5 files changed

Lines changed: 71 additions & 12 deletions

File tree

libs/SDL

Submodule SDL updated 1250 files

src/main.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,11 @@ void initApplication(SDL_Window* window) {
128128
VKA(vkAllocateCommandBuffers(context->device, &allocateInfo, &commandBuffers[i]));
129129
}
130130

131-
createBuffer(context, &vertexBuffer, sizeof(vertexData), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
132-
void* data;
133-
VKA(vkMapMemory(context->device, vertexBuffer.memory, 0, sizeof(vertexData), 0, &data));
134-
memcpy(data, vertexData, sizeof(vertexData));
135-
VK(vkUnmapMemory(context->device, vertexBuffer.memory));
136-
137-
createBuffer(context, &indexBuffer, sizeof(indexData), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
138-
VKA(vkMapMemory(context->device, indexBuffer.memory, 0, sizeof(indexData), 0, &data));
139-
memcpy(data, indexData, sizeof(indexData));
140-
VK(vkUnmapMemory(context->device, indexBuffer.memory));
131+
createBuffer(context, &vertexBuffer, sizeof(vertexData), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
132+
uploadDataToBuffer(context, &vertexBuffer, vertexData, sizeof(vertexData));
133+
134+
createBuffer(context, &indexBuffer, sizeof(indexData), VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
135+
uploadDataToBuffer(context, &indexBuffer, indexData, sizeof(indexData));
141136
}
142137

143138
void recreateSwapchain() {

src/vulkan_base/vulkan_base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ VkRenderPass createRenderPass(VulkanContext* context, VkFormat format);
5656
void destroyRenderpass(VulkanContext* context, VkRenderPass renderPass);
5757

5858
void createBuffer(VulkanContext* context, VulkanBuffer* buffer, uint64_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryProperties);
59+
void uploadDataToBuffer(VulkanContext* context, VulkanBuffer* buffer, void* data, size_t size);
5960
void destroyBuffer(VulkanContext* context, VulkanBuffer* buffer);
6061

6162
VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFilename, const char* fragmentShaderFilename, VkRenderPass renderPass, uint32_t width, uint32_t height, VkVertexInputAttributeDescription* attributes, uint32_t numAttributes, VkVertexInputBindingDescription* binding);

src/vulkan_base/vulkan_device.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,17 @@ bool createLogicalDevice(VulkanContext* context, uint32_t deviceExtensionCount,
116116
context->graphicsQueue.familyIndex = graphicsQueueIndex;
117117
VK(vkGetDeviceQueue(context->device, graphicsQueueIndex, 0, &context->graphicsQueue.queue));
118118

119+
VkPhysicalDeviceMemoryProperties deviceMemoryProperties;
120+
VK(vkGetPhysicalDeviceMemoryProperties(context->physicalDevice, &deviceMemoryProperties));
121+
LOG_INFO("Num device memory heaps: ", deviceMemoryProperties.memoryHeapCount);
122+
for (uint32_t i = 0; i < deviceMemoryProperties.memoryHeapCount; ++i) {
123+
const char* isDeviceLocal = "false";
124+
if (deviceMemoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
125+
isDeviceLocal = "true";
126+
}
127+
LOG_INFO("Heap ", i, ": Size:", deviceMemoryProperties.memoryHeaps[i].size, "bytes Device local: ", isDeviceLocal);
128+
}
129+
119130
return true;
120131
}
121132

src/vulkan_base/vulkan_utils.cpp

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ uint32_t findMemoryType(VulkanContext* context, uint32_t typeFilter, VkMemoryPro
1010
// Check if required properties are satisfied
1111
if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & memoryProperties) == memoryProperties) {
1212
// Return this memory type index
13+
LOG_INFO("Using memory heap index ", deviceMemoryProperties.memoryTypes[i].heapIndex);
1314
return i;
1415
}
1516
}
1617
}
1718

18-
// No matching avaialble memroy type found
19+
// No matching avaialble memory type found
1920
assert(false);
2021
return UINT32_MAX;
2122
}
@@ -41,6 +42,57 @@ void createBuffer(VulkanContext* context, VulkanBuffer* buffer, uint64_t size, V
4142
VKA(vkBindBufferMemory(context->device, buffer->buffer, buffer->memory, 0));
4243
}
4344

45+
void uploadDataToBuffer(VulkanContext* context, VulkanBuffer* buffer, void* data, size_t size) {
46+
#if 0
47+
void* mapped;
48+
VKA(vkMapMemory(context->device, buffer->memory, 0, size, 0, &mapped));
49+
memcpy(mapped, data, size);
50+
VK(vkUnmapMemory(context->device, buffer->memory));
51+
#else
52+
// Upload with staging buffer
53+
VulkanQueue* queue = &context->graphicsQueue;
54+
VkCommandPool commandPool;
55+
VkCommandBuffer commandBuffer;
56+
VulkanBuffer stagingBuffer;
57+
createBuffer(context, &stagingBuffer, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
58+
void* mapped;
59+
VKA(vkMapMemory(context->device, stagingBuffer.memory, 0, size, 0, &mapped));
60+
memcpy(mapped, data, size);
61+
VK(vkUnmapMemory(context->device, stagingBuffer.memory));
62+
{
63+
VkCommandPoolCreateInfo createInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
64+
createInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
65+
createInfo.queueFamilyIndex = queue->familyIndex;
66+
VKA(vkCreateCommandPool(context->device, &createInfo, 0, &commandPool));
67+
}
68+
{
69+
VkCommandBufferAllocateInfo allocateInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
70+
allocateInfo.commandPool = commandPool;
71+
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
72+
allocateInfo.commandBufferCount = 1;
73+
VKA(vkAllocateCommandBuffers(context->device, &allocateInfo, &commandBuffer));
74+
}
75+
76+
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
77+
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
78+
VKA(vkBeginCommandBuffer(commandBuffer, &beginInfo));
79+
80+
VkBufferCopy region = { 0, 0, size };
81+
VK(vkCmdCopyBuffer(commandBuffer, stagingBuffer.buffer, buffer->buffer, 1, &region));
82+
83+
VKA(vkEndCommandBuffer(commandBuffer));
84+
85+
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
86+
submitInfo.commandBufferCount = 1;
87+
submitInfo.pCommandBuffers = &commandBuffer;
88+
VKA(vkQueueSubmit(queue->queue, 1, &submitInfo, VK_NULL_HANDLE));
89+
VKA(vkQueueWaitIdle(queue->queue));
90+
91+
VK(vkDestroyCommandPool(context->device, commandPool, 0));
92+
destroyBuffer(context, &stagingBuffer);
93+
#endif
94+
}
95+
4496
void destroyBuffer(VulkanContext* context, VulkanBuffer* buffer) {
4597
VK(vkDestroyBuffer(context->device, buffer->buffer, 0));
4698
// Assumes that the buffer owns its own memory block

0 commit comments

Comments
 (0)