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
118
119
120
121
122
123
124
125
|
#pragma once
#include "rend_internal.h"
#include "rend_vk_internal.h"
#include <vulkan/vulkan_core.h>
struct RendVkImage {
VkDevice logical_device;
VkImage handle;
VkImageView view;
VkMemoryRequirements requirements;
VkImageType img_type;
uint32_t width, height;
VkFormat format;
VkImageTiling tiling;
VkImageUsageFlags usage;
uint32_t depth;
uint32_t mip_levels;
uint32_t layers;
VkSampleCountFlags sample_count_flags;
VkSharingMode sharing_mode;
RendMemory *memory;
};
static RendVkImage
rend_vk_image_create(VkDevice logical_device, VkImageType img_type, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage, VkMemoryPropertyFlags memory_flags, uint32_t depth, uint32_t mip_levels, uint32_t layers,
VkSampleCountFlags sample_count_flags, VkSharingMode sharing_mode)
{
RendVkImage image = {
.handle = VK_NULL_HANDLE,
.memory = VK_NULL_HANDLE,
.logical_device = logical_device,
.img_type = img_type,
.width = width,
.height = height,
.format = format,
.tiling = tiling,
.usage = usage,
.depth = depth,
.mip_levels = mip_levels,
.layers = layers,
.sample_count_flags = sample_count_flags,
.sharing_mode = sharing_mode
};
VkImageCreateInfo img_create_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
img_create_info.imageType = img_type;
img_create_info.extent.width = width;
img_create_info.extent.height = height;
img_create_info.extent.depth = depth;
img_create_info.mipLevels = mip_levels;
img_create_info.arrayLayers = layers;
img_create_info.format = format;
img_create_info.tiling = tiling;
img_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
img_create_info.usage = usage;
img_create_info.samples = sample_count_flags;
img_create_info.sharingMode = sharing_mode;
if (vkCreateImage(logical_device, &img_create_info, vk_allocator, &image.handle) != VK_SUCCESS) {
return image;
}
return image;
}
static uint32_t
rend_vk_image_required_memory_type(RendVkImage *img)
{
assert(img->memory == NULL && "Image already bound to memory");
VkMemoryRequirements memory_requirements = {0};
vkGetImageMemoryRequirements(img->logical_device, img->handle, &memory_requirements);
img->requirements = memory_requirements;
return memory_requirements.memoryTypeBits;
}
static void
rend_vk_image_bind_memory(RendVkImage *img, RendMemory *memory)
{
assert(img->memory == NULL && "Image already bound to memory");
vkBindImageMemory(img->logical_device, img->handle, (VkDeviceMemory) memory->device_memory, memory->offset);
}
static void
rend_vk_image_destroy(RendVkImage *img)
{
if (img->view) {
vkDestroyImageView(img->logical_device, img->view, vk_allocator);
img->view = 0;
}
if (img->handle) {
vkDestroyImage(img->logical_device, img->handle, vk_allocator);
img->handle = 0;
}
}
static void
rend_vk_image_view_create(RendVkImage *image, VkImageViewType view_type, VkImageAspectFlags view_aspect_flags)
{
VkImageViewCreateInfo view_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = image->handle,
.format = image->format,
.viewType = view_type,
.subresourceRange.aspectMask = view_aspect_flags,
.subresourceRange.baseMipLevel = 0, // offset starts at 0
.subresourceRange.levelCount = image->mip_levels, // number of mips
.subresourceRange.baseArrayLayer = 0, // offset starts at 0
.subresourceRange.layerCount = image->layers, // number of layers
};
vkCreateImageView(image->logical_device, &view_create_info, vk_allocator, &image->view);
}
static uint64_t
rend_vk_image_address(RendVkImage *image)
{
assert(image->memory == NULL && "Image already bound to memory");
return (uint64_t) image->memory->device_memory + image->memory->offset;
}
|