use device local buffer instead of host's
This commit is contained in:
parent
115e92ec23
commit
eb269cc88e
1 changed files with 91 additions and 43 deletions
134
main.cpp
134
main.cpp
|
|
@ -107,8 +107,6 @@ private:
|
|||
createSynchronizationObjects();
|
||||
|
||||
createVertexBuffer();
|
||||
allocateVertexBufferMemory();
|
||||
sendVertexBufferData();
|
||||
}
|
||||
|
||||
void mainLoop() {
|
||||
|
|
@ -787,57 +785,104 @@ private:
|
|||
return {};
|
||||
}
|
||||
|
||||
void allocateVertexBufferMemory() {
|
||||
VkMemoryRequirements memoryRequirements;
|
||||
vkGetBufferMemoryRequirements(mDevice, mVertexBuffer, &memoryRequirements);
|
||||
void createVertexBuffer() {
|
||||
size_t size = vertices.size() * sizeof(vertices[0]);
|
||||
|
||||
// FIXME : use explicit memory flushing instead of coherent_bit
|
||||
auto memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||
VkBuffer stagingBuffer;
|
||||
VkDeviceMemory stagingBufferMemory;
|
||||
|
||||
createBuffer(&stagingBuffer, &stagingBufferMemory,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
|
||||
{
|
||||
void* memory;
|
||||
vkMapMemory(mDevice, stagingBufferMemory, 0, size, 0, &memory);
|
||||
memcpy(memory, vertices.data(), size);
|
||||
vkUnmapMemory(mDevice, stagingBufferMemory);
|
||||
}
|
||||
|
||||
createBuffer(&mVertexBuffer, &mVertexBufferMemory,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, size,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||
|
||||
copyBuffer(stagingBuffer, mVertexBuffer, size);
|
||||
|
||||
destroyBuffer(stagingBuffer, stagingBufferMemory);
|
||||
}
|
||||
|
||||
void copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size) {
|
||||
VkCommandBufferAllocateInfo allocateInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.commandPool = mCommandPool,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1
|
||||
};
|
||||
|
||||
VkCommandBuffer commandBuffer;
|
||||
vkAllocateCommandBuffers(mDevice, &allocateInfo, &commandBuffer);
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
};
|
||||
|
||||
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
||||
|
||||
VkBufferCopy copyRegion {
|
||||
.srcOffset = 0,
|
||||
.dstOffset = 0,
|
||||
.size = size,
|
||||
};
|
||||
|
||||
vkCmdCopyBuffer(commandBuffer, src, dst, 1, ©Region);
|
||||
vkEndCommandBuffer(commandBuffer);
|
||||
|
||||
VkSubmitInfo submitInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &commandBuffer,
|
||||
};
|
||||
|
||||
vkQueueSubmit(mGraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
|
||||
vkQueueWaitIdle(mGraphicsQueue);
|
||||
|
||||
vkFreeCommandBuffers(mDevice, mCommandPool, 1, &commandBuffer);
|
||||
}
|
||||
|
||||
void createBuffer(VkBuffer *buffer, VkDeviceMemory *memory, VkMemoryPropertyFlags properties, VkDeviceSize size,
|
||||
VkBufferUsageFlags usage) {
|
||||
|
||||
VkBufferCreateInfo createInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = size,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
|
||||
if (vkCreateBuffer(mDevice, &createInfo, nullptr, buffer) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create vertex buffer");
|
||||
}
|
||||
|
||||
VkMemoryRequirements memoryRequirements;
|
||||
vkGetBufferMemoryRequirements(mDevice, *buffer, &memoryRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = memoryRequirements.size,
|
||||
.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, memoryFlags),
|
||||
.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, properties),
|
||||
};
|
||||
|
||||
if (vkAllocateMemory(mDevice, &allocateInfo, nullptr, &mVertexBufferMemory) != VK_SUCCESS) {
|
||||
if (vkAllocateMemory(mDevice, &allocateInfo, nullptr, memory) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to allocate vertex buffer memory");
|
||||
}
|
||||
|
||||
vkBindBufferMemory(mDevice, mVertexBuffer, mVertexBufferMemory, 0);
|
||||
vkBindBufferMemory(mDevice, *buffer, *memory, 0);
|
||||
}
|
||||
|
||||
void sendVertexBufferData() {
|
||||
size_t memoryLength = vertices.size() * sizeof(vertices[0]);
|
||||
void* memory;
|
||||
|
||||
if (vkMapMemory(mDevice, mVertexBufferMemory, 0, memoryLength, 0, &memory) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to map memory");
|
||||
}
|
||||
|
||||
memcpy(memory, vertices.data(), memoryLength);
|
||||
vkUnmapMemory(mDevice, mVertexBufferMemory);
|
||||
}
|
||||
|
||||
void freeVertexBufferMemory() {
|
||||
vkFreeMemory(mDevice, mVertexBufferMemory, nullptr);
|
||||
}
|
||||
|
||||
void createVertexBuffer() {
|
||||
VkBufferCreateInfo createInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = vertices.size() * sizeof(vertices[0]),
|
||||
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
|
||||
if (vkCreateBuffer(mDevice, &createInfo, nullptr, &mVertexBuffer) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create vertex buffer");
|
||||
}
|
||||
}
|
||||
|
||||
void destroyVertexBuffer() {
|
||||
vkDestroyBuffer(mDevice, mVertexBuffer, nullptr);
|
||||
void destroyBuffer(VkBuffer buffer, VkDeviceMemory memory) {
|
||||
vkDestroyBuffer(mDevice, buffer, nullptr);
|
||||
vkFreeMemory(mDevice, memory, nullptr);
|
||||
}
|
||||
|
||||
void populateGraphicsCommandBuffer(VkCommandBuffer commandBuffer, uint32_t swapChainImageIndex) {
|
||||
|
|
@ -969,6 +1014,10 @@ private:
|
|||
*/
|
||||
}
|
||||
|
||||
void createBuffer() {
|
||||
|
||||
}
|
||||
|
||||
static VkVertexInputBindingDescription getShaderVertexInputDescription() {
|
||||
return {
|
||||
.binding = 0,
|
||||
|
|
@ -1004,8 +1053,7 @@ private:
|
|||
}
|
||||
|
||||
void cleanup() {
|
||||
freeVertexBufferMemory();
|
||||
destroyVertexBuffer();
|
||||
destroyBuffer(mVertexBuffer, mVertexBufferMemory);
|
||||
|
||||
destroySynchronizationObjects();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue