summaryrefslogtreecommitdiff
path: root/src/render/buffer.c
blob: 2765a24ccd41d96eb4ac472c1686c81ab0bd7ad7 (plain)
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);
}