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
|
#pragma once
#include "rend_internal.h"
#include <stdint.h>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>
typedef struct RendVkAllocatorState {
const char *name;
} RendVkAllocatorState;
typedef struct RendVkAllocatorHeader {
uint32_t offset;
} RendVkAllocatorHeader;
static bool rend_vk_allocator_is_power_of_two(uintptr_t x);
static void *rend_vk_allocator_alloc(void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
static void *rend_vk_allocator_realloc(void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
static void rend_vk_allocator_free(void *pUserData, void *pMemory);
static void rend_vk_allocator_internal_notification(void *pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
static void rend_vk_allocator_free_notification(void *pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
static VkAllocationCallbacks rend_vk_allocator = {
.pfnAllocation = rend_vk_allocator_alloc,
.pfnReallocation = rend_vk_allocator_realloc,
.pfnFree = rend_vk_allocator_free,
.pfnInternalAllocation = rend_vk_allocator_internal_notification,
.pfnInternalFree = rend_vk_allocator_free_notification,
};
static const char* rend_vk_allocator_scope_name[] = {
[VK_SYSTEM_ALLOCATION_SCOPE_CACHE] = "Cache",
[VK_SYSTEM_ALLOCATION_SCOPE_COMMAND] = "Command",
[VK_SYSTEM_ALLOCATION_SCOPE_DEVICE] = "Device",
[VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE] = "Instance",
[VK_SYSTEM_ALLOCATION_SCOPE_OBJECT] = "Object",
};
static bool
rend_vk_allocator_is_power_of_two(uintptr_t x)
{
return (x & (x-1)) == 0;
}
static uintptr_t
rend_vk_allocator_align_forward(uintptr_t ptr, size_t align)
{
uintptr_t p, a, modulo;
assert(rend_vk_allocator_is_power_of_two(align));
p = ptr;
a = (uintptr_t)align;
modulo = p & (a-1);
if (modulo != 0) {
p += a - modulo;
}
return p;
}
static void*
rend_vk_allocator_alloc(void *pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
size_t total_size = size + alignment + sizeof (RendVkAllocatorHeader);
uint8_t *raw_ptr = malloc(total_size);
uintptr_t unaligned_addr = (uintptr_t)(raw_ptr + sizeof (RendVkAllocatorHeader));
uint8_t *aligned_ptr = (uint8_t*)rend_vk_allocator_align_forward(unaligned_addr, alignment);
RendVkAllocatorHeader *header = (RendVkAllocatorHeader*) aligned_ptr - 1;
header->offset = aligned_ptr - raw_ptr;
PDEBUG("[VK_ALLOC] %p - bytes %lu with alignment %lu - scope %s",
aligned_ptr, size, alignment, rend_vk_allocator_scope_name[allocationScope]);
return (void*) aligned_ptr;
}
static void*
rend_vk_allocator_realloc(void *pUserData, void *pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
{
if (!pOriginal) return rend_vk_allocator_alloc(pUserData, size, alignment, allocationScope);
if (size == 0) {
rend_vk_allocator_free(pUserData, pOriginal);
return NULL;
}
void *new_ptr = rend_vk_allocator_alloc(pUserData, size, alignment, allocationScope);
if (!new_ptr) return NULL;
memcpy(new_ptr, pOriginal, size);
rend_vk_allocator_free(pUserData, pOriginal);
return new_ptr;
}
static void
rend_vk_allocator_free(void *pUserData, void *pMemory)
{
RendVkAllocatorHeader *ptr = pMemory;
uint8_t *raw_ptr = pMemory;
raw_ptr -= (ptr-1)->offset;
PDEBUG("[VK_FREE] %p", ptr);
free(raw_ptr);
}
static void
rend_vk_allocator_internal_notification(void *pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
PDEBUG("[VK_ALLOC_INTERNAL] bytes %lu - scope %s",
size, rend_vk_allocator_scope_name[allocationScope]);
}
static void
rend_vk_allocator_free_notification(void *pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
{
PDEBUG("[VK_FREE_INTERNAL] bytes %lu - scope %s",
size, rend_vk_allocator_scope_name[allocationScope]);
}
|