Browse Source

Use index buffer.

master
Draklaw 4 years ago
parent
commit
9af8d5149d
  1. 106
      src/Vulkan/Context.cpp
  2. 10
      src/Vulkan/Context.h
  3. 93
      src/VulkanTutorial.cpp
  4. 3
      src/VulkanTutorial.h

106
src/Vulkan/Context.cpp

@ -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,33 +909,35 @@ 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:
{
auto stream = [severity]() {
switch(severity) {
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
return logger.debug();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
return logger.info();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
return logger.warning();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
return logger.error();
}
return logger.debug();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
return logger.info();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
return logger.warning();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
return logger.error();
}();
switch(type) {
case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
stream << "[vk:general] ";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
stream << "[vk:validation] ";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
stream << "[vk:performance] ";
break;
}
return logger.debug();
}();
switch(type) {
case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
stream << "[vk:general] ";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
stream << "[vk:validation] ";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
stream << "[vk:performance] ";
break;
}
stream << data->pMessage;
stream << data->pMessage;
}
if(severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
abort();

10
src/Vulkan/Context.h

@ -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);

93
src/VulkanTutorial.cpp

@ -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
);
void* buffer = nullptr;
vkMapMemory(
m_context.device(),
tmp_buffer_memory,
0,
buffer_size,
0,
&buffer
size, (char*)vertices.data(),
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
m_context.queue_family(GRAPHIC_QUEUE)
);
}
memcpy(buffer, vertices.data(), size_t(buffer_size));
vkUnmapMemory(
m_context.device(),
tmp_buffer_memory
);
void VulkanTutorial::create_index_buffer() {
if(m_index_buffer != VK_NULL_HANDLE)
return;
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
);

3
src/VulkanTutorial.h

@ -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;
};

Loading…
Cancel
Save