Skip to content

Commit

Permalink
uses staging buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Sep 7, 2023
1 parent 3fa8c3c commit 671923c
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 30 deletions.
9 changes: 9 additions & 0 deletions include/Renderer/vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,15 @@ namespace Renderer

uint32_t findMemoryType(uint32_t typeFiller, VkMemoryPropertyFlags properties);

void createBuffer
(
VkDeviceSize size,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties,
VkBuffer & buffer, VkDeviceMemory & bufferMemory
);

void copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size);
};

}
Expand Down
2 changes: 2 additions & 0 deletions launch-wine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cd build && wine64 ./HelloVK
cd ..
136 changes: 106 additions & 30 deletions src/Renderer/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -825,43 +825,42 @@ namespace Renderer

void VulkanRenderer::createVertexBuffer()
{
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = sizeof(vertices[0]) * vertices.size();
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

VkDeviceSize bufferSize = sizeof(vertices[0])*vertices.size();

if (vkCreateBuffer(device, &bufferInfo, nullptr, &vertexBuffer) != VK_SUCCESS)
{
throw std::runtime_error("Failed to create vertex buffer");
}
// first create a staging buffer to transfer into from the host
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;

VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, vertexBuffer, &memRequirements);
createBuffer
(
bufferSize,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
stagingBuffer,
stagingBufferMemory
);

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
void * data;
vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
std::memcpy(data, vertices.data(), (size_t) bufferSize);
vkUnmapMemory(device, stagingBufferMemory);

allocInfo.memoryTypeIndex = findMemoryType
(
memRequirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
// create normal buffer

if (vkAllocateMemory(device, &allocInfo, nullptr, &vertexBufferMemory) != VK_SUCCESS)
{
throw std::runtime_error("Failed to allocate vertex buffer memory");
}
createBuffer
(
bufferSize,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
vertexBuffer,
vertexBufferMemory
);

// last is an offset in memory
vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0);
copyBuffer(stagingBuffer, vertexBuffer, bufferSize);

void * data;
vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, &data);
std::memcpy(data, vertices.data(), (size_t) bufferInfo.size);
vkUnmapMemory(device, vertexBufferMemory);
vkDestroyBuffer(device, stagingBuffer, nullptr);
vkFreeMemory(device, stagingBufferMemory, nullptr);

}

Expand Down Expand Up @@ -1100,4 +1099,81 @@ namespace Renderer
}


void VulkanRenderer::createBuffer
(
VkDeviceSize size,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties,
VkBuffer & buffer, VkDeviceMemory & bufferMemory
)
{
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS)
{
throw std::runtime_error("Failed to create vertex buffer");
}

VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, buffer, &memRequirements);

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;

allocInfo.memoryTypeIndex = findMemoryType
(
memRequirements.memoryTypeBits,
properties
);

if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS)
{
throw std::runtime_error("Failed to allocate vertex buffer memory");
}

// last is an offset in memory
vkBindBufferMemory(device, buffer, bufferMemory, 0);
}

void VulkanRenderer::copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size)
{
VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandPool = commandPool;
allocInfo.commandBufferCount = 1;

VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer);

VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

vkBeginCommandBuffer(commandBuffer, &beginInfo);

VkBufferCopy copyRegion{};
copyRegion.srcOffset = 0;
copyRegion.dstOffset = 0;
copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, src, dst, 1, &copyRegion);

vkEndCommandBuffer(commandBuffer);

VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;

vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(graphicsQueue);

vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer);
}

}

0 comments on commit 671923c

Please sign in to comment.