summaryrefslogtreecommitdiff
path: root/rend_vk_internal.h
blob: e85a6dcae52ab2bf5dfd75b9a67c4a4533f68c88 (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
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