comparison semiconginev2/old/vulkan/memory.nim @ 1218:56781cc0fc7c compiletime-tests

did: renamge main package
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 21:01:37 +0700
parents semicongine/old/vulkan/memory.nim@a3eb305bcac2
children
comparison
equal deleted inserted replaced
1217:f819a874058f 1218:56781cc0fc7c
1 import std/strformat
2
3 import ../core
4 import ./device
5
6 type
7 MemoryHeap = object
8 size*: uint64
9 flags*: seq[VkMemoryHeapFlagBits]
10 index*: uint32
11 MemoryType* = object
12 heap*: MemoryHeap
13 flags*: seq[VkMemoryPropertyFlagBits]
14 index*: uint32
15 PhyscialDeviceMemoryProperties = object
16 heaps*: seq[MemoryHeap]
17 types*: seq[MemoryType]
18 DeviceMemory* = object
19 device*: Device
20 vk*: VkDeviceMemory
21 size*: uint64
22 memoryType*: MemoryType
23 case canMap*: bool
24 of false: discard
25 of true: data*: pointer
26 needsFlushing*: bool
27 MemoryRequirements* = object
28 size*: uint64
29 alignment*: uint64
30 memoryTypes*: seq[MemoryType]
31
32 func `$`*(memoryType: MemoryType): string =
33 &"Memorytype {memoryType.flags} (heap size: {memoryType.heap.size}, heap flags: {memoryType.heap.flags})"
34
35 proc SelectBestMemoryType*(types: seq[MemoryType], requireMappable: bool, preferVRAM: bool, preferAutoFlush: bool): MemoryType =
36 # todo: we assume there is always at least one memory type that is mappable
37 assert types.len > 0
38 var highestRating = 0'f
39 result = types[0]
40 for t in types:
41 var rating = float(t.heap.size) / 1_000_000'f # select biggest heap if all else equal
42 if requireMappable and VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in t.flags:
43 rating += 1000
44 if preferVRAM and VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT in t.flags:
45 rating += 500
46 if preferAutoFlush and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in t.flags:
47 rating += 100
48 if rating > highestRating:
49 highestRating = rating
50 result = t
51
52 proc GetMemoryProperties*(physicalDevice: VkPhysicalDevice): PhyscialDeviceMemoryProperties =
53 var physicalProperties: VkPhysicalDeviceMemoryProperties
54 vkGetPhysicalDeviceMemoryProperties(physicalDevice, addr physicalProperties)
55 for i in 0 ..< physicalProperties.memoryHeapCount:
56 result.heaps.add MemoryHeap(
57 size: physicalProperties.memoryHeaps[i].size,
58 flags: toEnums(physicalProperties.memoryHeaps[i].flags),
59 index: i,
60 )
61 for i in 0 ..< physicalProperties.memoryTypeCount:
62 result.types.add MemoryType(
63 heap: result.heaps[physicalProperties.memoryTypes[i].heapIndex],
64 flags: toEnums(physicalProperties.memoryTypes[i].propertyFlags),
65 index: i,
66 )
67
68 proc Allocate*(device: Device, size: uint64, memoryType: MemoryType): DeviceMemory =
69 assert device.vk.Valid
70 assert size > 0
71 result = DeviceMemory(
72 device: device,
73 size: size,
74 memoryType: memoryType,
75 canMap: VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in memoryType.flags,
76 needsFlushing: not (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in memoryType.flags),
77 )
78
79 var allocationInfo = VkMemoryAllocateInfo(
80 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
81 allocationSize: size,
82 memoryTypeIndex: result.memoryType.index,
83 )
84
85 checkVkResult vkAllocateMemory(
86 device.vk,
87 addr allocationInfo,
88 nil,
89 addr result.vk
90 )
91
92 if result.canMap:
93 checkVkResult result.device.vk.vkMapMemory(
94 memory = result.vk,
95 offset = VkDeviceSize(0),
96 size = VkDeviceSize(result.size),
97 flags = VkMemoryMapFlags(0), # unused up to Vulkan 1.3
98 ppData = addr(result.data)
99 )
100
101 # flush host -> device
102 proc Flush*(memory: DeviceMemory, offset = 0'u64, size = 0'u64) =
103 assert memory.device.vk.Valid
104 assert memory.vk.Valid
105 assert memory.needsFlushing
106
107 var actualSize = size
108 if actualSize == 0:
109 actualSize = memory.size
110 var flushrange = VkMappedMemoryRange(
111 sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
112 memory: memory.vk,
113 offset: VkDeviceSize(offset),
114 size: VkDeviceSize(size)
115 )
116 checkVkResult memory.device.vk.vkFlushMappedMemoryRanges(memoryRangeCount = 1, pMemoryRanges = addr(flushrange))
117
118 # flush device -> host
119 proc Invalidate*(memory: DeviceMemory, offset = 0'u64, size = 0'u64) =
120 assert memory.device.vk.Valid
121 assert memory.vk.Valid
122 assert memory.needsFlushing
123
124 var actualSize = size
125 if actualSize == 0:
126 actualSize = memory.size
127 var flushrange = VkMappedMemoryRange(
128 sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
129 memory: memory.vk,
130 offset: VkDeviceSize(offset),
131 size: VkDeviceSize(size)
132 )
133 checkVkResult memory.device.vk.vkInvalidateMappedMemoryRanges(memoryRangeCount = 1, pMemoryRanges = addr(flushrange))
134
135 proc Free*(memory: var DeviceMemory) =
136 assert memory.device.vk.Valid
137 assert memory.vk.Valid
138
139 memory.device.vk.vkFreeMemory(memory.vk, nil)
140 memory.vk.Reset