/* buffer.c Vulkan buffer functions Copyright (C) 2020 Bill Currie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "QF/mathlib.h" #include "QF/Vulkan/buffer.h" #include "QF/Vulkan/device.h" #include "QF/Vulkan/instance.h" VkBuffer QFV_CreateBuffer (qfv_device_t *device, VkDeviceSize size, VkBufferUsageFlags usage) { VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; VkBufferCreateInfo createInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 0, 0, size, usage, VK_SHARING_MODE_EXCLUSIVE, 0, 0 }; VkBuffer buffer; dfunc->vkCreateBuffer (dev, &createInfo, 0, &buffer); return buffer; } VkDeviceMemory QFV_AllocBufferMemory (qfv_device_t *device, VkBuffer buffer, VkMemoryPropertyFlags properties, VkDeviceSize size, VkDeviceSize offset) { VkDevice dev = device->dev; qfv_physdev_t *physdev = device->physDev; VkPhysicalDeviceMemoryProperties *memprops = &physdev->memory_properties; qfv_devfuncs_t *dfunc = device->funcs; VkMemoryRequirements requirements; dfunc->vkGetBufferMemoryRequirements (dev, buffer, &requirements); size = max (size, offset + requirements.size); VkDeviceMemory object = 0; for (uint32_t type = 0; type < memprops->memoryTypeCount; type++) { if ((requirements.memoryTypeBits & (1 << type)) && ((memprops->memoryTypes[type].propertyFlags & properties) == properties)) { VkMemoryAllocateInfo allocate_info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 0, size, type }; VkResult res = dfunc->vkAllocateMemory (dev, &allocate_info, 0, &object); if (res == VK_SUCCESS) { break; } } } return object; } int QFV_BindBufferMemory (qfv_device_t *device, VkBuffer buffer, VkDeviceMemory object, VkDeviceSize offset) { VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; VkResult res = dfunc->vkBindBufferMemory (dev, buffer, object, offset); return res == VK_SUCCESS; } qfv_bufferbarrierset_t * QFV_CreateBufferTransitions (qfv_buffertransition_t *transitions, int numTransitions) { qfv_bufferbarrierset_t *barrierset; barrierset = DARRAY_ALLOCFIXED (*barrierset, numTransitions, malloc); for (int i = 0; i < numTransitions; i++) { barrierset->a[i].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; barrierset->a[i].pNext = 0; barrierset->a[i].srcAccessMask = transitions[i].srcAccess; barrierset->a[i].dstAccessMask = transitions[i].dstAccess; barrierset->a[i].srcQueueFamilyIndex = transitions[i].srcQueueFamily; barrierset->a[i].dstQueueFamilyIndex = transitions[i].dstQueueFamily; barrierset->a[i].buffer = transitions[i].buffer; barrierset->a[i].offset = transitions[i].offset; barrierset->a[i].size = transitions[i].size; } return barrierset; } VkBufferView QFV_CreateBufferView (qfv_device_t *device, VkBuffer buffer, VkFormat format, VkDeviceSize offset, VkDeviceSize size) { VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; VkBufferViewCreateInfo createInfo = { VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, 0, 0, buffer, format, offset, size, }; VkBufferView view; dfunc->vkCreateBufferView (dev, &createInfo, 0, &view); return view; } VkDeviceSize QFV_NextOffset (VkDeviceSize current, const VkMemoryRequirements *requirements) { VkDeviceSize align = requirements->alignment - 1; return ((current + align) & ~align); }