Browse Source

Move memory allocation stuff to VulkanContext.

master
Draklaw 4 years ago
parent
commit
22cd51b5df
  1. 67
      src/Vulkan/Context.cpp
  2. 6
      src/Vulkan/Context.h
  3. 2
      src/Vulkan/Swapchain.cpp
  4. 54
      src/VulkanTutorial.cpp

67
src/Vulkan/Context.cpp

@ -270,22 +270,70 @@ VkShaderModule Context::create_shader_module_from_file(const char* path) {
return VK_NULL_HANDLE;
}
int32_t Context::find_memory(uint32_t type_filter, VkMemoryPropertyFlags properties) {
VkPhysicalDeviceMemoryProperties memory_properties;
vkGetPhysicalDeviceMemoryProperties(
m_physical_device,
&memory_properties
);
for(uint32_t type_index = 0; type_index < memory_properties.memoryTypeCount; type_index += 1) {
int32_t Context::find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties) {
for(uint32_t type_index = 0; type_index < m_memory_properties.memoryTypeCount; type_index += 1) {
if(((1 << type_index) & type_filter) &&
(memory_properties.memoryTypes[type_index].propertyFlags & properties) == properties)
(m_memory_properties.memoryTypes[type_index].propertyFlags & properties) == properties)
return type_index;
}
return -1;
}
VkDeviceMemory Context::allocate_memory(VkDeviceSize size, uint32_t type_filter, VkMemoryPropertyFlags properties) {
uint32_t memory_type = find_memory_type(type_filter, properties);
VkMemoryAllocateInfo malloc_info {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = size,
.memoryTypeIndex = memory_type,
};
VkDeviceMemory memory = VK_NULL_HANDLE;
if(vkAllocateMemory(m_device, &malloc_info, nullptr, &memory) != VK_SUCCESS)
throw std::runtime_error("failed to allocate device memory");
return memory;
}
std::tuple<VkBuffer, VkDeviceMemory> Context::create_buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_properties) {
VkDeviceMemory memory = VK_NULL_HANDLE;
VkBuffer buffer = VK_NULL_HANDLE;
VkBufferCreateInfo buffer_info {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
if(vkCreateBuffer(
m_device,
&buffer_info,
nullptr,
&buffer
) != VK_SUCCESS)
throw std::runtime_error("failed to create buffer");
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(
m_device,
buffer,
&memory_requirements
);
memory = allocate_memory(
memory_requirements.size,
memory_requirements.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
vkBindBufferMemory(m_device, buffer, memory, 0);
return { buffer, memory };
}
void Context::destroy_instance(VkInstance& instance) {
if(instance == nullptr)
@ -531,6 +579,7 @@ void Context::choose_physical_device(const ContextSettings& settings) {
if(maybe_properties) {
m_physical_device = physical_device;
m_physical_device_properties = *maybe_properties;
vkGetPhysicalDeviceMemoryProperties(m_physical_device, &m_memory_properties);
break;
}
}

6
src/Vulkan/Context.h

@ -100,7 +100,10 @@ public:
VkShaderModule create_shader_module(const std::vector<char> bytecode);
VkShaderModule create_shader_module_from_file(const char* path);
int32_t find_memory(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);
std::tuple<VkBuffer, VkDeviceMemory> create_buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_properties);
void destroy_instance(VkInstance& instance);
@ -157,6 +160,7 @@ private:
VkDebugUtilsMessengerEXT m_debug_messenger = VK_NULL_HANDLE;
VkPhysicalDevice m_physical_device = nullptr;
VkPhysicalDeviceProperties m_physical_device_properties;
VkPhysicalDeviceMemoryProperties m_memory_properties;
VkDevice m_device = nullptr;
std::vector<uint32_t> m_queue_families;

2
src/Vulkan/Swapchain.cpp

@ -385,6 +385,8 @@ void Swapchain::destroy() {
}
void Swapchain::recreate() {
vkDeviceWaitIdle(m_context->device());
destroy();
create();
}

54
src/VulkanTutorial.cpp

@ -436,68 +436,26 @@ void VulkanTutorial::create_vertex_buffer() {
if(m_vertex_buffer != VK_NULL_HANDLE)
return;
VkBufferCreateInfo buffer_info {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = sizeof(vertices[0]) * vertices.size(),
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
if(vkCreateBuffer(
m_context.device(),
&buffer_info,
nullptr,
&m_vertex_buffer
) != VK_SUCCESS)
throw std::runtime_error("failed to create vertex buffer");
VkDeviceSize buffer_size = sizeof(vertices[0]) * vertices.size();
VkMemoryRequirements memory_requirements;
vkGetBufferMemoryRequirements(
m_context.device(),
m_vertex_buffer,
&memory_requirements
);
const auto memory_type = m_context.find_memory(
memory_requirements.memoryTypeBits,
std::tie(m_vertex_buffer, m_vertex_buffer_memory) = m_context.create_buffer(
buffer_size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
if(memory_type < 0)
throw std::runtime_error("failed to find suitable memory type for vertex buffer");
VkMemoryAllocateInfo alloc_info {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = memory_requirements.size,
.memoryTypeIndex = uint32_t(memory_type),
};
if(vkAllocateMemory(
m_context.device(),
&alloc_info,
nullptr,
&m_vertex_buffer_memory
) != VK_SUCCESS)
throw std::runtime_error("failed to allocate vertex buffer memory");
vkBindBufferMemory(
m_context.device(),
m_vertex_buffer,
m_vertex_buffer_memory,
0
);
void* buffer = nullptr;
vkMapMemory(
m_context.device(),
m_vertex_buffer_memory,
0,
buffer_info.size,
buffer_size,
0,
&buffer
);
memcpy(buffer, vertices.data(), size_t(buffer_info.size));
memcpy(buffer, vertices.data(), size_t(buffer_size));
vkUnmapMemory(
m_context.device(),

Loading…
Cancel
Save