Use index buffer.
This commit is contained in:
@@ -338,6 +338,60 @@ std::tuple<VkBuffer, VkDeviceMemory> Context::create_buffer(VkDeviceSize size, V
|
||||
return { buffer, memory };
|
||||
}
|
||||
|
||||
std::tuple<VkBuffer, VkDeviceMemory> Context::create_buffer(
|
||||
VkDeviceSize size, char* data,
|
||||
VkBufferUsageFlags usage,
|
||||
VkMemoryPropertyFlags memory_properties,
|
||||
uint32_t dst_queue_family
|
||||
) {
|
||||
VkBuffer tmp_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory tmp_buffer_memory = VK_NULL_HANDLE;
|
||||
std::tie(tmp_buffer, tmp_buffer_memory) = create_buffer(
|
||||
size,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||
);
|
||||
auto const tmp_buffer_guard = make_guard([&] {
|
||||
free_memory(tmp_buffer_memory);
|
||||
destroy_buffer(tmp_buffer);
|
||||
});
|
||||
|
||||
VkBuffer buffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory buffer_memory = VK_NULL_HANDLE;
|
||||
std::tie(buffer, buffer_memory) = create_buffer(
|
||||
size,
|
||||
usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
memory_properties
|
||||
);
|
||||
|
||||
void* device_buffer = nullptr;
|
||||
vkMapMemory(
|
||||
m_device,
|
||||
tmp_buffer_memory,
|
||||
0,
|
||||
size,
|
||||
0,
|
||||
&device_buffer
|
||||
);
|
||||
|
||||
memcpy(device_buffer, data, size_t(size));
|
||||
|
||||
vkUnmapMemory(
|
||||
m_device,
|
||||
tmp_buffer_memory
|
||||
);
|
||||
|
||||
copy_buffer(
|
||||
buffer,
|
||||
tmp_buffer,
|
||||
dst_queue_family,
|
||||
size
|
||||
);
|
||||
|
||||
return std::make_tuple(buffer, buffer_memory);
|
||||
}
|
||||
|
||||
void Context::copy_buffer(VkBuffer dst, VkBuffer src, uint32_t dst_queue_family, VkDeviceSize size) {
|
||||
VkCommandBufferAllocateInfo alloc_info {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
@@ -387,6 +441,8 @@ void Context::copy_buffer(VkBuffer dst, VkBuffer src, uint32_t dst_queue_family,
|
||||
|
||||
vkEndCommandBuffer(command_buffer);
|
||||
|
||||
vkResetFences(m_device, 1, &m_transfer_fence);
|
||||
|
||||
VkSubmitInfo submit_info {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = 1,
|
||||
@@ -853,6 +909,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL Context::log_debug_message(
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* data,
|
||||
void* user_data
|
||||
) {
|
||||
{
|
||||
auto stream = [severity]() {
|
||||
switch(severity) {
|
||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
|
||||
@@ -880,6 +937,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL Context::log_debug_message(
|
||||
}
|
||||
|
||||
stream << data->pMessage;
|
||||
}
|
||||
|
||||
if(severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||
abort();
|
||||
|
||||
@@ -103,7 +103,15 @@ public:
|
||||
int32_t find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties);
|
||||
VkDeviceMemory allocate_memory(VkDeviceSize size, uint32_t type_filter, VkMemoryPropertyFlags properties);
|
||||
|
||||
std::tuple<VkBuffer, VkDeviceMemory> create_buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_properties);
|
||||
std::tuple<VkBuffer, VkDeviceMemory> create_buffer(
|
||||
VkDeviceSize size,
|
||||
VkBufferUsageFlags usage,
|
||||
VkMemoryPropertyFlags memory_properties);
|
||||
std::tuple<VkBuffer, VkDeviceMemory> create_buffer(
|
||||
VkDeviceSize size, char* buffer,
|
||||
VkBufferUsageFlags usage,
|
||||
VkMemoryPropertyFlags memory_properties,
|
||||
uint32_t dst_queue_family);
|
||||
void copy_buffer(VkBuffer dst, VkBuffer src, uint32_t dst_queue_family, VkDeviceSize size);
|
||||
|
||||
|
||||
|
||||
@@ -40,9 +40,15 @@ std::array<VkVertexInputAttributeDescription, 2> Vertex::attributes_description(
|
||||
|
||||
|
||||
const std::vector<Vertex> vertices = {
|
||||
{{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}},
|
||||
{{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}},
|
||||
{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}
|
||||
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
|
||||
{{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}},
|
||||
{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}},
|
||||
{{0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}},
|
||||
};
|
||||
|
||||
const std::vector<uint16_t> indices = {
|
||||
0, 1, 2,
|
||||
2, 1, 3,
|
||||
};
|
||||
|
||||
|
||||
@@ -66,12 +72,13 @@ void VulkanTutorial::initialize(SDL_Window* window) {
|
||||
.with_window(window);
|
||||
m_context.initialize(context_settings);
|
||||
|
||||
create_command_pool();
|
||||
create_vertex_buffer();
|
||||
create_index_buffer();
|
||||
|
||||
auto const swapchain_settings = Vulkan::SwapchainSettings(&m_context)
|
||||
.with_queue(m_context.queue_family(GRAPHIC_QUEUE));
|
||||
m_swapchain.initialize(swapchain_settings);
|
||||
|
||||
create_command_pool();
|
||||
create_vertex_buffer();
|
||||
}
|
||||
|
||||
void VulkanTutorial::shutdown() {
|
||||
@@ -84,8 +91,10 @@ void VulkanTutorial::shutdown() {
|
||||
|
||||
m_context.free_memory(m_vertex_buffer_memory);
|
||||
m_context.destroy_command_pool(m_command_pool);
|
||||
m_context.destroy_buffer(m_vertex_buffer);
|
||||
m_context.free_memory(m_index_buffer_memory);
|
||||
m_context.destroy_buffer(m_index_buffer);
|
||||
m_context.free_memory(m_vertex_buffer_memory);
|
||||
m_context.destroy_buffer(m_vertex_buffer);
|
||||
|
||||
for(VkSemaphore semaphore: m_render_done)
|
||||
m_context.destroy_semaphore(semaphore);
|
||||
@@ -436,57 +445,29 @@ void VulkanTutorial::create_vertex_buffer() {
|
||||
if(m_vertex_buffer != VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
VkDeviceSize buffer_size = sizeof(vertices[0]) * vertices.size();
|
||||
|
||||
VkBuffer tmp_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory tmp_buffer_memory = VK_NULL_HANDLE;
|
||||
std::tie(tmp_buffer, tmp_buffer_memory) = m_context.create_buffer(
|
||||
buffer_size,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||
);
|
||||
auto const tmp_buffer_guard = make_guard([&] {
|
||||
m_context.free_memory(tmp_buffer_memory);
|
||||
m_context.destroy_buffer(tmp_buffer);
|
||||
});
|
||||
|
||||
VkDeviceSize size = sizeof(vertices[0]) * vertices.size();
|
||||
std::tie(m_vertex_buffer, m_vertex_buffer_memory) = m_context.create_buffer(
|
||||
buffer_size,
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
||||
size, (char*)vertices.data(),
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
m_context.queue_family(GRAPHIC_QUEUE)
|
||||
);
|
||||
}
|
||||
|
||||
void* buffer = nullptr;
|
||||
vkMapMemory(
|
||||
m_context.device(),
|
||||
tmp_buffer_memory,
|
||||
0,
|
||||
buffer_size,
|
||||
0,
|
||||
&buffer
|
||||
);
|
||||
void VulkanTutorial::create_index_buffer() {
|
||||
if(m_index_buffer != VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
memcpy(buffer, vertices.data(), size_t(buffer_size));
|
||||
|
||||
vkUnmapMemory(
|
||||
m_context.device(),
|
||||
tmp_buffer_memory
|
||||
);
|
||||
|
||||
m_context.copy_buffer(
|
||||
m_vertex_buffer,
|
||||
tmp_buffer,
|
||||
m_context.queue_family(GRAPHIC_QUEUE),
|
||||
buffer_size
|
||||
VkDeviceSize size = sizeof(indices[0]) * indices.size();
|
||||
std::tie(m_index_buffer, m_index_buffer_memory) = m_context.create_buffer(
|
||||
size, (char*)indices.data(),
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
m_context.queue_family(GRAPHIC_QUEUE)
|
||||
);
|
||||
}
|
||||
|
||||
void VulkanTutorial::create_command_buffers() {
|
||||
create_command_pool();
|
||||
create_vertex_buffer();
|
||||
|
||||
m_command_buffers.resize(m_framebuffers.size());
|
||||
|
||||
VkCommandBufferAllocateInfo allocate_info {
|
||||
@@ -564,11 +545,19 @@ void VulkanTutorial::create_command_buffers() {
|
||||
offsets
|
||||
);
|
||||
|
||||
vkCmdDraw(
|
||||
vkCmdBindIndexBuffer(
|
||||
command_buffer,
|
||||
uint32_t(vertices.size()),
|
||||
m_index_buffer,
|
||||
0,
|
||||
VK_INDEX_TYPE_UINT16
|
||||
);
|
||||
|
||||
vkCmdDrawIndexed(
|
||||
command_buffer,
|
||||
uint32_t(indices.size()),
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ private:
|
||||
void create_framebuffers();
|
||||
void create_command_pool();
|
||||
void create_vertex_buffer();
|
||||
void create_index_buffer();
|
||||
void create_command_buffers();
|
||||
|
||||
private:
|
||||
@@ -61,6 +62,8 @@ private:
|
||||
VkCommandPool m_command_pool = VK_NULL_HANDLE;
|
||||
VkBuffer m_vertex_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory m_vertex_buffer_memory = VK_NULL_HANDLE;
|
||||
VkBuffer m_index_buffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory m_index_buffer_memory = VK_NULL_HANDLE;
|
||||
std::vector<VkCommandBuffer> m_command_buffers;
|
||||
std::vector<VkSemaphore> m_render_done;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user