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 }; 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) { void Context::copy_buffer(VkBuffer dst, VkBuffer src, uint32_t dst_queue_family, VkDeviceSize size) {
VkCommandBufferAllocateInfo alloc_info { VkCommandBufferAllocateInfo alloc_info {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_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); vkEndCommandBuffer(command_buffer);
vkResetFences(m_device, 1, &m_transfer_fence);
VkSubmitInfo submit_info { VkSubmitInfo submit_info {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.commandBufferCount = 1, .commandBufferCount = 1,
@ -853,33 +909,35 @@ VKAPI_ATTR VkBool32 VKAPI_CALL Context::log_debug_message(
const VkDebugUtilsMessengerCallbackDataEXT* data, const VkDebugUtilsMessengerCallbackDataEXT* data,
void* user_data void* user_data
) { ) {
auto stream = [severity]() { {
switch(severity) { auto stream = [severity]() {
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: 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(); return logger.debug();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: }();
return logger.info();
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: switch(type) {
return logger.warning(); case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: stream << "[vk:general] ";
return logger.error(); 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) if(severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
abort(); abort();

10
src/Vulkan/Context.h

@ -103,7 +103,15 @@ public:
int32_t find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties); int32_t find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties);
VkDeviceMemory allocate_memory(VkDeviceSize size, 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); 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 = { const std::vector<Vertex> vertices = {
{{0.0f, -0.5f}, {1.0f, 0.0f, 0.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, 1.0f, 0.0f}},
{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.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); .with_window(window);
m_context.initialize(context_settings); m_context.initialize(context_settings);
create_command_pool();
create_vertex_buffer();
create_index_buffer();
auto const swapchain_settings = Vulkan::SwapchainSettings(&m_context) auto const swapchain_settings = Vulkan::SwapchainSettings(&m_context)
.with_queue(m_context.queue_family(GRAPHIC_QUEUE)); .with_queue(m_context.queue_family(GRAPHIC_QUEUE));
m_swapchain.initialize(swapchain_settings); m_swapchain.initialize(swapchain_settings);
create_command_pool();
create_vertex_buffer();
} }
void VulkanTutorial::shutdown() { void VulkanTutorial::shutdown() {
@ -84,8 +91,10 @@ void VulkanTutorial::shutdown() {
m_context.free_memory(m_vertex_buffer_memory); m_context.free_memory(m_vertex_buffer_memory);
m_context.destroy_command_pool(m_command_pool); 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.free_memory(m_vertex_buffer_memory);
m_context.destroy_buffer(m_vertex_buffer);
for(VkSemaphore semaphore: m_render_done) for(VkSemaphore semaphore: m_render_done)
m_context.destroy_semaphore(semaphore); m_context.destroy_semaphore(semaphore);
@ -436,57 +445,29 @@ void VulkanTutorial::create_vertex_buffer() {
if(m_vertex_buffer != VK_NULL_HANDLE) if(m_vertex_buffer != VK_NULL_HANDLE)
return; return;
VkDeviceSize buffer_size = sizeof(vertices[0]) * vertices.size(); VkDeviceSize 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);
});
std::tie(m_vertex_buffer, m_vertex_buffer_memory) = m_context.create_buffer( std::tie(m_vertex_buffer, m_vertex_buffer_memory) = m_context.create_buffer(
buffer_size, size, (char*)vertices.data(),
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
| VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_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
); );
}
memcpy(buffer, vertices.data(), size_t(buffer_size)); void VulkanTutorial::create_index_buffer() {
if(m_index_buffer != VK_NULL_HANDLE)
vkUnmapMemory( return;
m_context.device(),
tmp_buffer_memory
);
m_context.copy_buffer( VkDeviceSize size = sizeof(indices[0]) * indices.size();
m_vertex_buffer, std::tie(m_index_buffer, m_index_buffer_memory) = m_context.create_buffer(
tmp_buffer, size, (char*)indices.data(),
m_context.queue_family(GRAPHIC_QUEUE), VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
buffer_size VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
m_context.queue_family(GRAPHIC_QUEUE)
); );
} }
void VulkanTutorial::create_command_buffers() { void VulkanTutorial::create_command_buffers() {
create_command_pool();
create_vertex_buffer();
m_command_buffers.resize(m_framebuffers.size()); m_command_buffers.resize(m_framebuffers.size());
VkCommandBufferAllocateInfo allocate_info { VkCommandBufferAllocateInfo allocate_info {
@ -564,11 +545,19 @@ void VulkanTutorial::create_command_buffers() {
offsets offsets
); );
vkCmdDraw( vkCmdBindIndexBuffer(
command_buffer, command_buffer,
uint32_t(vertices.size()), m_index_buffer,
0,
VK_INDEX_TYPE_UINT16
);
vkCmdDrawIndexed(
command_buffer,
uint32_t(indices.size()),
1, 1,
0, 0,
0,
0 0
); );

3
src/VulkanTutorial.h

@ -46,6 +46,7 @@ private:
void create_framebuffers(); void create_framebuffers();
void create_command_pool(); void create_command_pool();
void create_vertex_buffer(); void create_vertex_buffer();
void create_index_buffer();
void create_command_buffers(); void create_command_buffers();
private: private:
@ -61,6 +62,8 @@ private:
VkCommandPool m_command_pool = VK_NULL_HANDLE; VkCommandPool m_command_pool = VK_NULL_HANDLE;
VkBuffer m_vertex_buffer = VK_NULL_HANDLE; VkBuffer m_vertex_buffer = VK_NULL_HANDLE;
VkDeviceMemory m_vertex_buffer_memory = 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<VkCommandBuffer> m_command_buffers;
std::vector<VkSemaphore> m_render_done; std::vector<VkSemaphore> m_render_done;
}; };

Loading…
Cancel
Save