Mercurial > games > semicongine
view semiconginev2/old/vulkan/memory.nim @ 1222:3c3d4d7a8ecd compiletime-tests
did: cleanup config file
author | sam <sam@basx.dev> |
---|---|
date | Wed, 17 Jul 2024 21:08:15 +0700 |
parents | 56781cc0fc7c |
children |
line wrap: on
line source
import std/strformat import ../core import ./device type MemoryHeap = object size*: uint64 flags*: seq[VkMemoryHeapFlagBits] index*: uint32 MemoryType* = object heap*: MemoryHeap flags*: seq[VkMemoryPropertyFlagBits] index*: uint32 PhyscialDeviceMemoryProperties = object heaps*: seq[MemoryHeap] types*: seq[MemoryType] DeviceMemory* = object device*: Device vk*: VkDeviceMemory size*: uint64 memoryType*: MemoryType case canMap*: bool of false: discard of true: data*: pointer needsFlushing*: bool MemoryRequirements* = object size*: uint64 alignment*: uint64 memoryTypes*: seq[MemoryType] func `$`*(memoryType: MemoryType): string = &"Memorytype {memoryType.flags} (heap size: {memoryType.heap.size}, heap flags: {memoryType.heap.flags})" proc SelectBestMemoryType*(types: seq[MemoryType], requireMappable: bool, preferVRAM: bool, preferAutoFlush: bool): MemoryType = # todo: we assume there is always at least one memory type that is mappable assert types.len > 0 var highestRating = 0'f result = types[0] for t in types: var rating = float(t.heap.size) / 1_000_000'f # select biggest heap if all else equal if requireMappable and VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in t.flags: rating += 1000 if preferVRAM and VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT in t.flags: rating += 500 if preferAutoFlush and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in t.flags: rating += 100 if rating > highestRating: highestRating = rating result = t proc GetMemoryProperties*(physicalDevice: VkPhysicalDevice): PhyscialDeviceMemoryProperties = var physicalProperties: VkPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties(physicalDevice, addr physicalProperties) for i in 0 ..< physicalProperties.memoryHeapCount: result.heaps.add MemoryHeap( size: physicalProperties.memoryHeaps[i].size, flags: toEnums(physicalProperties.memoryHeaps[i].flags), index: i, ) for i in 0 ..< physicalProperties.memoryTypeCount: result.types.add MemoryType( heap: result.heaps[physicalProperties.memoryTypes[i].heapIndex], flags: toEnums(physicalProperties.memoryTypes[i].propertyFlags), index: i, ) proc Allocate*(device: Device, size: uint64, memoryType: MemoryType): DeviceMemory = assert device.vk.Valid assert size > 0 result = DeviceMemory( device: device, size: size, memoryType: memoryType, canMap: VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in memoryType.flags, needsFlushing: not (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in memoryType.flags), ) var allocationInfo = VkMemoryAllocateInfo( sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, allocationSize: size, memoryTypeIndex: result.memoryType.index, ) checkVkResult vkAllocateMemory( device.vk, addr allocationInfo, nil, addr result.vk ) if result.canMap: checkVkResult result.device.vk.vkMapMemory( memory = result.vk, offset = VkDeviceSize(0), size = VkDeviceSize(result.size), flags = VkMemoryMapFlags(0), # unused up to Vulkan 1.3 ppData = addr(result.data) ) # flush host -> device proc Flush*(memory: DeviceMemory, offset = 0'u64, size = 0'u64) = assert memory.device.vk.Valid assert memory.vk.Valid assert memory.needsFlushing var actualSize = size if actualSize == 0: actualSize = memory.size var flushrange = VkMappedMemoryRange( sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, memory: memory.vk, offset: VkDeviceSize(offset), size: VkDeviceSize(size) ) checkVkResult memory.device.vk.vkFlushMappedMemoryRanges(memoryRangeCount = 1, pMemoryRanges = addr(flushrange)) # flush device -> host proc Invalidate*(memory: DeviceMemory, offset = 0'u64, size = 0'u64) = assert memory.device.vk.Valid assert memory.vk.Valid assert memory.needsFlushing var actualSize = size if actualSize == 0: actualSize = memory.size var flushrange = VkMappedMemoryRange( sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, memory: memory.vk, offset: VkDeviceSize(offset), size: VkDeviceSize(size) ) checkVkResult memory.device.vk.vkInvalidateMappedMemoryRanges(memoryRangeCount = 1, pMemoryRanges = addr(flushrange)) proc Free*(memory: var DeviceMemory) = assert memory.device.vk.Valid assert memory.vk.Valid memory.device.vk.vkFreeMemory(memory.vk, nil) memory.vk.Reset