Mercurial > games > semicongine
diff src/semicongine/vulkan/buffer.nim @ 156:134647ed5b60
did: refactor memory selection
author | Sam <sam@basx.dev> |
---|---|
date | Sat, 29 Apr 2023 16:50:43 +0700 |
parents | 321d3de6c78c |
children | 041a114db1dc |
line wrap: on
line diff
--- a/src/semicongine/vulkan/buffer.nim Thu Apr 27 21:16:13 2023 +0700 +++ b/src/semicongine/vulkan/buffer.nim Sat Apr 29 16:50:43 2023 +0700 @@ -20,6 +20,11 @@ of false: discard of true: memory*: DeviceMemory + MemoryRequirements = object + size: uint64 + alignment: uint64 + memoryTypes: seq[MemoryType] + proc `==`*(a, b: Buffer): bool = a.vk == b.vk @@ -27,39 +32,43 @@ func `$`*(buffer: Buffer): string = &"Buffer(vk: {buffer.vk}, size: {buffer.size}, usage: {buffer.usage})" +proc requirements(buffer: Buffer): MemoryRequirements = + assert buffer.vk.valid + assert buffer.device.vk.valid + var req: VkMemoryRequirements + buffer.device.vk.vkGetBufferMemoryRequirements(buffer.vk, addr req) + result.size = req.size + result.alignment = req.alignment + let memorytypes = buffer.device.physicaldevice.vk.getMemoryProperties().types + for i in 0 ..< sizeof(req.memoryTypeBits) * 8: + if ((req.memoryTypeBits shr i) and 1) == 1: + result.memoryTypes.add memorytypes[i] -proc allocateMemory(buffer: var Buffer, preferVRAM: bool, requiresMapping: bool, autoFlush: bool) = +proc allocateMemory(buffer: var Buffer, requireMappable: bool, preferVRAM: bool, preferAutoFlush: bool) = assert buffer.device.vk.valid assert buffer.memoryAllocated == false - var flags: seq[VkMemoryPropertyFlagBits] - if requiresMapping: - flags.add VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT - - if preferVRAM and buffer.device.hasMemoryWith(flags & @[VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT]): - flags.add VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT - - if requiresMapping and autoFlush and buffer.device.hasMemoryWith(flags & @[VK_MEMORY_PROPERTY_HOST_COHERENT_BIT]): - flags.add VK_MEMORY_PROPERTY_HOST_COHERENT_BIT - - assert buffer.device.hasMemoryWith(flags) - + let requirements = buffer.requirements() + let memoryType = requirements.memoryTypes.selectBestMemoryType( + requireMappable=requireMappable, + preferVRAM=preferVRAM, + preferAutoFlush=preferAutoFlush + ) buffer.memoryAllocated = true - debug "Allocating memory for buffer: ", buffer.size, " bytes ", flags - buffer.memory = buffer.device.allocate(buffer.size, flags) + debug "Allocating memory for buffer: ", buffer.size, " bytes of type ", memoryType + buffer.memory = buffer.device.allocate(requirements.size, memoryType) if buffer.memory.canMap: checkVkResult buffer.device.vk.vkBindBufferMemory(buffer.vk, buffer.memory.vk, VkDeviceSize(0)) - # currently no support for extended structure and concurrent/shared use # (shardingMode = VK_SHARING_MODE_CONCURRENT not supported) proc createBuffer*( device: Device, size: uint64, usage: openArray[VkBufferUsageFlagBits], + requireMappable: bool, preferVRAM: bool, - requiresMapping: bool, - autoFlush=true, + preferAutoFlush=true, ): Buffer = assert device.vk.valid assert size > 0 @@ -67,7 +76,7 @@ result.device = device result.size = size result.usage = usage.toSeq - if not (requiresMapping or VK_BUFFER_USAGE_TRANSFER_DST_BIT in result.usage): + if not (requireMappable or VK_BUFFER_USAGE_TRANSFER_DST_BIT in result.usage): result.usage.add VK_BUFFER_USAGE_TRANSFER_DST_BIT var createInfo = VkBufferCreateInfo( sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, @@ -83,7 +92,7 @@ pAllocator=nil, pBuffer=addr result.vk ) - result.allocateMemory(preferVRAM, requiresMapping, autoFlush) + result.allocateMemory(requireMappable=requireMappable, preferVRAM=preferVRAM, preferAutoFlush=preferAutoFlush) proc copy*(src, dst: Buffer) = @@ -139,7 +148,7 @@ if dst.memory.needsFlushing: dst.memory.flush() else: # use staging buffer, slower but required if memory is not host visible - var stagingBuffer = dst.device.createBuffer(size, [VK_BUFFER_USAGE_TRANSFER_SRC_BIT], preferVRAM=false, requiresMapping=true, autoFlush=true) + var stagingBuffer = dst.device.createBuffer(size, [VK_BUFFER_USAGE_TRANSFER_SRC_BIT], requireMappable=true, preferVRAM=false, preferAutoFlush=true) stagingBuffer.setData(src, size, 0) stagingBuffer.copy(dst) stagingBuffer.destroy()