changeset 151:a46923cb0790

did: better memory selection
author Sam <sam@basx.dev>
date Thu, 27 Apr 2023 20:43:27 +0700
parents 7ed6f87a0fe1
children 260965aefc39
files src/semicongine/renderer.nim src/semicongine/vulkan/buffer.nim src/semicongine/vulkan/memory.nim src/semicongine/vulkan/pipeline.nim
diffstat 4 files changed, 30 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/renderer.nim	Thu Apr 27 01:58:16 2023 -0700
+++ b/src/semicongine/renderer.nim	Thu Apr 27 20:43:27 2023 +0700
@@ -85,8 +85,8 @@
     data.indexBuffer = renderer.device.createBuffer(
       size=indicesBufferSize,
       usage=[VK_BUFFER_USAGE_INDEX_BUFFER_BIT],
-      useVRAM=true,
-      mappable=false,
+      preferVRAM=true,
+      requiresMapping=false,
     )
 
   # one vertex data buffer per memory location
@@ -108,8 +108,8 @@
       data.vertexBuffers[location] = renderer.device.createBuffer(
         size=bufferSize,
         usage=[VK_BUFFER_USAGE_VERTEX_BUFFER_BIT],
-        useVRAM=location in [VRAM, VRAMVisible],
-        mappable=location in [VRAMVisible, RAM],
+        preferVRAM=location in [VRAM, VRAMVisible],
+        requiresMapping=location in [VRAMVisible, RAM],
       )
       perLocationOffsets[location] = 0
 
--- a/src/semicongine/vulkan/buffer.nim	Thu Apr 27 01:58:16 2023 -0700
+++ b/src/semicongine/vulkan/buffer.nim	Thu Apr 27 20:43:27 2023 +0700
@@ -27,16 +27,18 @@
   &"Buffer(vk: {buffer.vk}, size: {buffer.size}, usage: {buffer.usage})"
 
 
-proc allocateMemory(buffer: var Buffer, useVRAM: bool, mappable: bool, autoFlush: bool) =
+proc allocateMemory(buffer: var Buffer, preferVRAM: bool, requiresMapping: bool, autoFlush: bool) =
   assert buffer.device.vk.valid
   assert buffer.memoryAllocated == false
 
   var flags: seq[VkMemoryPropertyFlagBits]
-  if useVRAM:
+  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 mappable:
-    flags.add VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
-  if autoFlush:
+
+  if autoFlush and buffer.device.hasMemoryWith(flags & @[VK_MEMORY_PROPERTY_HOST_COHERENT_BIT]):
     flags.add VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
 
   buffer.memoryAllocated = true
@@ -50,8 +52,8 @@
   device: Device,
   size: uint64,
   usage: openArray[VkBufferUsageFlagBits],
-  useVRAM: bool,
-  mappable: bool,
+  preferVRAM: bool,
+  requiresMapping: bool,
   autoFlush=true,
 ): Buffer =
   assert device.vk.valid
@@ -60,7 +62,7 @@
   result.device = device
   result.size = size
   result.usage = usage.toSeq
-  if not (mappable or VK_BUFFER_USAGE_TRANSFER_DST_BIT in result.usage):
+  if not (requiresMapping 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,
@@ -76,7 +78,7 @@
     pAllocator=nil,
     pBuffer=addr result.vk
   )
-  result.allocateMemory(useVRAM, mappable, autoFlush)
+  result.allocateMemory(preferVRAM, requiresMapping, autoFlush)
 
 
 proc copy*(src, dst: Buffer) =
@@ -132,7 +134,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], useVRAM=false, mappable=true, autoFlush=true)
+    var stagingBuffer = dst.device.createBuffer(size, [VK_BUFFER_USAGE_TRANSFER_SRC_BIT], preferVRAM=false, requiresMapping=true, autoFlush=true)
     stagingBuffer.setData(src, size, 0)
     stagingBuffer.copy(dst)
     stagingBuffer.destroy()
--- a/src/semicongine/vulkan/memory.nim	Thu Apr 27 01:58:16 2023 -0700
+++ b/src/semicongine/vulkan/memory.nim	Thu Apr 27 20:43:27 2023 +0700
@@ -42,6 +42,16 @@
       index: i,
     )
 
+proc hasMemoryWith*(device: Device, requiredFlags: openArray[VkMemoryPropertyFlagBits]): bool =
+  for mtype in device.physicalDevice.vk.getPhysicalDeviceMemoryProperties.types:
+    var hasAllFlags = true
+    for flag in requiredFlags:
+      if not (flag in mtype.flags):
+        hasAllFlags = false
+        break
+    if hasAllFlags:
+      return true
+
 proc allocate*(device: Device, size: uint64, flags: openArray[VkMemoryPropertyFlagBits]): DeviceMemory =
   assert device.vk.valid
   assert size > 0
@@ -90,6 +100,7 @@
       ppData=addr(result.data)
     )
 
+#[ 
 proc allocate*(device: Device, size: uint64, useVRAM: bool, mappable: bool, autoFlush: bool): DeviceMemory =
   var flags: seq[VkMemoryPropertyFlagBits]
   if useVRAM:
@@ -99,6 +110,7 @@
   if autoFlush:
     flags.add VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
   device.allocate(size=size, flags=flags)
+]#
 
 # flush host -> device
 proc flush*(memory: DeviceMemory, offset=0'u64, size=0'u64) =
--- a/src/semicongine/vulkan/pipeline.nim	Thu Apr 27 01:58:16 2023 -0700
+++ b/src/semicongine/vulkan/pipeline.nim	Thu Apr 27 20:43:27 2023 +0700
@@ -50,8 +50,8 @@
     var buffer = pipeline.device.createBuffer(
       size=uniformBufferSize,
       usage=[VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT],
-      useVRAM=true,
-      mappable=true,
+      preferVRAM=true,
+      requiresMapping=true,
     )
     pipeline.uniformBuffers.add buffer
     pipeline.descriptorSets[i].setDescriptorSet(buffer)