/* * Copyright 2022 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "base_buffer.hpp" namespace VK { const CommandChain BaseBuffer::loader{ {&BaseBuffer::load_buffer, &BaseBuffer::unload_buffer}, {&BaseBuffer::load_memory, &BaseBuffer::unload_memory} }; void BaseBuffer::load_buffer(void *obj) { auto self = static_cast(obj); VkBufferCreateInfo buffer_info = {}; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.pNext = nullptr; buffer_info.flags = 0; buffer_info.size = self->device_size; buffer_info.usage = self->buffer_usage; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; buffer_info.queueFamilyIndexCount = 0; buffer_info.pQueueFamilyIndices = nullptr; if(vkCreateBuffer( self->device->device, &buffer_info, nullptr, &self->buffer) != VK_SUCCESS) throw CommandError{"Failed to create vertex buffer."}; } void BaseBuffer::unload_buffer(void *obj) { auto self = static_cast(obj); if(self->buffer != VK_NULL_HANDLE) vkDestroyBuffer(self->device->device, self->buffer, nullptr); } void BaseBuffer::load_memory(void *obj) { auto self = static_cast(obj); VkMemoryRequirements memory_requirements; vkGetBufferMemoryRequirements( self->device->device, self->buffer, &memory_requirements); VkPhysicalDeviceMemoryProperties memory_properties; vkGetPhysicalDeviceMemoryProperties( self->device->physical_device, &memory_properties); VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.pNext = nullptr; alloc_info.allocationSize = memory_requirements.size; if(!self->device->select_memory_type( &alloc_info.memoryTypeIndex, &memory_requirements, self->memory_properties)) throw CommandError{"Could not allocate memory for Vulkan vertex buffer."}; if(vkAllocateMemory(self->device->device, &alloc_info, nullptr, &self->device_memory) != VK_SUCCESS) throw CommandError{"Could not allocate memory for Vulkan vertex buffer."}; vkBindBufferMemory( self->device->device, self->buffer, self->device_memory, 0); } void BaseBuffer::unload_memory(void *obj) { auto self = static_cast(obj); if(self->device_memory != VK_NULL_HANDLE) vkFreeMemory(self->device->device, self->device_memory, nullptr); } }