Move memory allocation stuff to VulkanContext.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -385,6 +385,8 @@ void Swapchain::destroy() {
|
||||
}
|
||||
|
||||
void Swapchain::recreate() {
|
||||
vkDeviceWaitIdle(m_context->device());
|
||||
|
||||
destroy();
|
||||
create();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
VkDeviceSize buffer_size = sizeof(vertices[0]) * vertices.size();
|
||||
|
||||
if(vkCreateBuffer(
|
||||
m_context.device(),
|
||||
&buffer_info,
|
||||
nullptr,
|
||||
&m_vertex_buffer
|
||||
) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to create vertex buffer");
|
||||
|
||||
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(),
|
||||
|
||||
Reference in New Issue
Block a user