1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include "render/buffer.h"
#include "render/renderer.h"
#include <sys/types.h>
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);
}
|