#include "render/buffer.h" #include "render/renderer.h" #include static ssize_t find_memory_type(struct renderer *ren, uint32_t filter, VkMemoryPropertyFlags props) { VkPhysicalDeviceMemoryProperties mem_props; vkGetPhysicalDeviceMemoryProperties(ren->phy_gpus.chosen->gpu, &mem_props); for (size_t i = 0; i < mem_props.memoryTypeCount; i++) if (filter & (1 << i) && (mem_props.memoryTypes[i].propertyFlags & props) == props) return i; return -1; } VkResult buffer_create(struct renderer *ren, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags props, struct buffer *buf) { VkBufferCreateInfo buffer_info = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .size = size, .usage = usage, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, }; VkResult res = vkCreateBuffer(ren->gpu.device, &buffer_info, NULL, &buf->buffer); if (res != VK_SUCCESS) return res; VkMemoryRequirements mem_reqs; vkGetBufferMemoryRequirements(ren->gpu.device, buf->buffer, &mem_reqs); ssize_t mem_type_index = find_memory_type(ren, mem_reqs.memoryTypeBits, props); if (mem_type_index == -1) return VK_ERROR_UNKNOWN; VkMemoryAllocateInfo alloc_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = mem_reqs.size, .memoryTypeIndex = mem_type_index }; res = vkAllocateMemory(ren->gpu.device, &alloc_info, NULL, &buf->memory); if (res != VK_SUCCESS) return res; vkBindBufferMemory(ren->gpu.device, buf->buffer, buf->memory, 0); return VK_SUCCESS; } void buffer_destroy(struct renderer *ren, struct buffer *buf) { vkDestroyBuffer(ren->gpu.device, buf->buffer, NULL); vkFreeMemory(ren->gpu.device, buf->memory, NULL); } VkResult create_image(struct renderer *ren, VkExtent2D extent, uint32_t mip_level, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags props, VkImage *img, VkDeviceMemory *memory) { VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .imageType = VK_IMAGE_TYPE_2D, .extent = { .width = extent.width, .height = extent.height, .depth = 1 }, .mipLevels = mip_level, .arrayLayers = 1, .format = format, .tiling = tiling, .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, .usage = usage, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, .samples = VK_SAMPLE_COUNT_1_BIT }; VkResult res = vkCreateImage(ren->gpu.device, &image_info, NULL, img); if (res != VK_SUCCESS) return res; VkMemoryRequirements mem_reqs; vkGetImageMemoryRequirements(ren->gpu.device, *img, &mem_reqs); VkMemoryAllocateInfo alloc_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = mem_reqs.size, .memoryTypeIndex = find_memory_type(ren, mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) }; res = vkAllocateMemory(ren->gpu.device, &alloc_info, NULL, memory); if (res != VK_SUCCESS) return res; return vkBindImageMemory(ren->gpu.device, *img, *memory, 0); } VkResult create_image_view(VkDevice gpu, VkImage image, VkFormat format, VkImageAspectFlags flags, VkImageView *view) { return vkCreateImageView(gpu, &(VkImageViewCreateInfo) { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .image = image, .viewType = VK_IMAGE_VIEW_TYPE_2D, .format = format, .components = { .r = VK_COMPONENT_SWIZZLE_IDENTITY, .g = VK_COMPONENT_SWIZZLE_IDENTITY, .b = VK_COMPONENT_SWIZZLE_IDENTITY, .a = VK_COMPONENT_SWIZZLE_IDENTITY, }, .subresourceRange = { .aspectMask = flags, .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, .layerCount = 1 } }, NULL, view); }