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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
#ifndef REND_VK_INTERNAL_H
#define REND_VK_INTERNAL_H
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>
#include <assert.h>
#define CHECK_VK_RESULT(r) \
{ \
assert(r == VK_SUCCESS && __LINE__); \
}
typedef struct RendVkImage RendVkImage;
typedef struct RendVkArenaAllocator RendVkArenaAllocator;
typedef struct RendVkSbta RendVkSbta;
typedef struct RendVkPendingCmd RendVkPendingCmd;
typedef struct RendVkDeferredCmds RendVkDeferredCmds;
typedef struct {
const char **extention_names_darray;
bool sampler_anisotropy;
bool discrete_gpu;
bool graphics;
bool present;
bool compute;
bool transfer;
} RendVkDevicespecs;
typedef struct {
uint32_t graphics_family_index;
uint32_t present_family_index;
uint32_t compute_family_index;
uint32_t transfer_family_index;
} RendVkQueueFamily;
typedef struct {
VkSurfaceCapabilitiesKHR capabilities;
VkSurfaceFormatKHR *format;
VkPresentModeKHR *present_modes;
uint32_t format_count;
uint32_t present_mode_count;
} RendVkSwapchainSupport;
typedef struct {
/* logical device handle */
VkDevice logical_device;
/* physical device limitation */
VkPhysicalDeviceProperties properties;
VkPhysicalDeviceMemoryProperties memory;
VkPhysicalDevice physical_device;
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceDescriptorBufferPropertiesEXT desc_props;
/* swapchain support */
VkSurfaceKHR surface;
RendVkSwapchainSupport swapchain_support;
VkFormat depth_format;
/* queues */
VkQueue graphics_queue;
VkQueue present_queue;
VkQueue compute_queue;
VkQueue transfer_queue;
uint32_t graphics_family_index;
uint32_t present_family_index;
uint32_t compute_family_index;
uint32_t transfer_family_index;
/* memory heap indices */
uint32_t host_index;
uint32_t device_index;
} RendVkDevice;
static VkInstance vk_instance = 0;
static VkDebugUtilsMessengerEXT vk_debug_messenger = 0;
static RendVkDevice vk_device = {0};
/* helper functions */
static int32_t rend_vk_memory_find_index(VkPhysicalDevice device, uint32_t type_filter, VkMemoryPropertyFlags property_flags);
/* rend_vk_device.c */
static bool rend_vk_device_create(VkSurfaceKHR surface, RendSpecs specs, RendVkDevice *out_device, uint32_t (*score_devices)(RendVkDevice *, RendSpecs, char **));
static uint32_t rend_vk_device_score_default(RendVkDevice *device, RendSpecs minimum_specs, char **required_extensions);
static void rend_vk_physical_device_query_swapchain_support(RendVkDevice *device);
static bool rend_vk_device_detect_depth_format(RendVkDevice *device);
static void rend_vk_device_destroy(void);
/* rend_vk_arena.c */
static RendVkArenaAllocator rend_vk_arena_create(VkDevice logical_device, VkPhysicalDevice physical_device, VkPhysicalDeviceLimits device_limits, VkAllocationCallbacks *allocator);
static uint32_t rend_vk_arena_add_page(RendVkArenaAllocator *arena, VkDeviceSize size, uint32_t heap_index, bool fit_to_alloc);
static RendMemory rend_vk_arena_alloc(RendVkArenaAllocator *arena, VkDeviceSize size, uint32_t heap_index);
static void rend_vk_arena_clear(RendVkArenaAllocator *arena, uint32_t memory_type);
static void rend_vk_arena_clear_all(RendVkArenaAllocator *arena);
static void rend_vk_arena_shrink(RendVkArenaAllocator *arena, uint32_t memory_type);
static void rend_vk_arena_destroy(RendVkArenaAllocator *arena);
/* rend_vk_command_queue.c */
static inline RendVkDeferredCmds rend_vk_cmdbuf_deferred_create(void);
static inline void rend_vk_cmdbuf_deferred_destroy(RendVkDeferredCmds *tracker);
static inline uint64_t rend_vk_cmdbuf_deferred_submit(RendVkDeferredCmds *tracker, VkCommandPool pool, VkCommandBuffer cmd, VkQueue queue, uint64_t wait_value, VkPipelineStageFlags2 wait_stage, VkPipelineStageFlags2 signal_stage);
static inline void rend_vk_cmdbuf_deferred_push(RendVkDeferredCmds *tracker, VkCommandPool pool, VkCommandBuffer cmd, uint64_t wait_value);
static inline void rend_vk_cmdbuf_deferred_flush(RendVkDeferredCmds *tracker);
/* rend_vk_image.c */
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);
static uint32_t rend_vk_image_required_memory_type(RendVkImage *img);
static void rend_vk_image_bind_memory(RendVkImage *image, RendMemory *memory);
static void rend_vk_image_destroy(RendVkImage *img);
static void rend_vk_image_view_create(RendVkImage *image, VkImageViewType view_type, VkImageAspectFlags view_aspect_flags);
static uint64_t rend_vk_image_address(RendVkImage *image);
static VkAllocationCallbacks *vk_allocator = 0; // we are only ever going to use one, either the default one or the custom one
static VkFormat vk_format_from_rend_format[] = {
[REND_FORMAT_R8_UNORM] = VK_FORMAT_R8_UNORM,
[REND_FORMAT_R8G8_UNORM] = VK_FORMAT_R8G8_UNORM,
[REND_FORMAT_R8G8B8A8_UNORM] = VK_FORMAT_R8G8B8A8_UNORM,
[REND_FORMAT_B8G8R8A8_UNORM] = VK_FORMAT_B8G8R8A8_UNORM,
[REND_FORMAT_R8G8B8A8_SRGB] = VK_FORMAT_R8G8B8A8_SRGB,
[REND_FORMAT_B8G8R8A8_SRGB] = VK_FORMAT_B8G8R8A8_SRGB,
[REND_FORMAT_R32_SFLOAT] = VK_FORMAT_R32_SFLOAT,
[REND_FORMAT_R32G32_SFLOAT] = VK_FORMAT_R32G32_SFLOAT,
[REND_FORMAT_R32G32B32_SFLOAT] = VK_FORMAT_R32G32B32_SFLOAT,
[REND_FORMAT_R32G32B32A32_SFLOAT]= VK_FORMAT_R32G32B32A32_SFLOAT,
[REND_FORMAT_R16_SFLOAT] = VK_FORMAT_R16_SFLOAT,
[REND_FORMAT_R16G16_SFLOAT] = VK_FORMAT_R16G16_SFLOAT,
[REND_FORMAT_R16G16B16A16_SFLOAT]= VK_FORMAT_R16G16B16A16_SFLOAT,
[REND_FORMAT_R32_UINT] = VK_FORMAT_R32_UINT,
[REND_FORMAT_R32_SINT] = VK_FORMAT_R32_SINT,
[REND_FORMAT_R32G32B32A32_UINT] = VK_FORMAT_R32G32B32A32_UINT,
[REND_FORMAT_R16G16B16A16_UINT] = VK_FORMAT_R16G16B16A16_UINT,
[REND_FORMAT_R8G8B8A8_UINT] = VK_FORMAT_R8G8B8A8_UINT,
[REND_FORMAT_D32_SFLOAT] = VK_FORMAT_D32_SFLOAT,
[REND_FORMAT_D24_UNORM_S8_UINT] = VK_FORMAT_D24_UNORM_S8_UINT,
[REND_FORMAT_D32_SFLOAT_S8_UINT] = VK_FORMAT_D32_SFLOAT_S8_UINT,
};
static VkPrimitiveTopology vk_topology[] = {
[REND_TOPOLOGY_TRIANGLE_LIST] = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
[REND_TOPOLOGY_TRIANGLE_STRIP] = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
[REND_TOPOLOGY_LINE_LIST] = VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
[REND_TOPOLOGY_LINE_STRIP] = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
[REND_TOPOLOGY_POINT_LIST] = VK_PRIMITIVE_TOPOLOGY_POINT_LIST
};
static VkPolygonMode vk_polymode[] = {
[REND_POLYGON_MODE_FILL] = VK_POLYGON_MODE_FILL,
[REND_POLYGON_MODE_LINE] = VK_POLYGON_MODE_LINE,
[REND_POLYGON_MODE_POINT] = VK_POLYGON_MODE_POINT,
};
static VkCullModeFlags vk_cullflags[] = {
[REND_CULL_MODE_NONE] = VK_CULL_MODE_NONE,
[REND_CULL_MODE_FRONT] = VK_CULL_MODE_FRONT_BIT,
[REND_CULL_MODE_BACK] = VK_CULL_MODE_BACK_BIT,
[REND_CULL_MODE_FRONT_AND_BACK] = VK_CULL_MODE_FRONT_AND_BACK,
};
static int32_t
rend_vk_memory_find_index(VkPhysicalDevice device, uint32_t type_filter, VkMemoryPropertyFlags property_flags)
{
VkPhysicalDeviceMemoryProperties memory_properties;
vkGetPhysicalDeviceMemoryProperties(device, &memory_properties);
for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++) {
if (type_filter & (1 << i) && (memory_properties.memoryTypes[i].propertyFlags & property_flags) == property_flags) {
return i;
}
}
return -1;
}
#endif
|