changeset 251:9289776cd61c

fix: add descriptor pool per scene, use zippy instead of zip
author sam <sam@basx.dev>
date Wed, 24 May 2023 01:30:36 +0700
parents 93bdbb969708
children f31d848ab551
files src/semicongine/engine.nim src/semicongine/platform/windows/window.nim src/semicongine/renderer.nim src/semicongine/resources.nim src/semicongine/resources/image.nim src/semicongine/vulkan/pipeline.nim
diffstat 6 files changed, 27 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/engine.nim	Tue May 23 18:17:15 2023 +0700
+++ b/src/semicongine/engine.nim	Wed May 24 01:30:36 2023 +0700
@@ -109,11 +109,11 @@
     engine.renderer.get.destroy()
   engine.renderer = some(engine.device.initRenderer(renderPass))
 
-proc addScene*(engine: var Engine, scene: Scene, vertexInput: seq[ShaderAttribute], transformAttribute="") =
+proc addScene*(engine: var Engine, scene: Scene, vertexInput: seq[ShaderAttribute], samplers: seq[ShaderAttribute], transformAttribute="") =
   assert engine.state != Destroyed
   assert transformAttribute == "" or transformAttribute in map(vertexInput, proc(a: ShaderAttribute): string = a.name)
   assert engine.renderer.isSome
-  engine.renderer.get.setupDrawableBuffers(scene, vertexInput, transformAttribute=transformAttribute)
+  engine.renderer.get.setupDrawableBuffers(scene, vertexInput, samplers, transformAttribute=transformAttribute)
 
 proc renderScene*(engine: var Engine, scene: var Scene) =
   assert engine.state == Running
--- a/src/semicongine/platform/windows/window.nim	Tue May 23 18:17:15 2023 +0700
+++ b/src/semicongine/platform/windows/window.nim	Wed May 24 01:30:36 2023 +0700
@@ -57,7 +57,8 @@
   of WM_MOUSEMOVE:
     currentEvents.add(Event(eventType: events.MouseMoved, x: GET_X_LPARAM(lParam), y: GET_Y_LPARAM(lParam)))
   of WM_MOUSEWHEEL:
-    currentEvents.add(Event(eventType: events.MouseWheel, amount: float32(GET_WHEEL_DELTA_WPARAM(wParam))))
+    currentEvents.add(Event(eventType: events.MouseWheel, amount: float32(GET_WHEEL_DELTA_WPARAM(wParam)) / WHEEL_DELTA))
+    echo GET_WHEEL_DELTA_WPARAM(wParam)
   else:
     return DefWindowProc(hwnd, uMsg, wParam, lParam)
 
--- a/src/semicongine/renderer.nim	Tue May 23 18:17:15 2023 +0700
+++ b/src/semicongine/renderer.nim	Wed May 24 01:30:36 2023 +0700
@@ -29,6 +29,7 @@
     attributeBindingNumber*: Table[string, int]
     transformAttribute: string # name of attribute that is used for per-instance mesh transformation
     entityTransformationCache: Table[Mesh, Mat4] # remembers last transformation, avoid to send GPU-updates if no changes
+    descriptorPool*: DescriptorPool
     descriptorSets*: Table[VkPipeline, seq[DescriptorSet]]
   Renderer* = object
     device: Device
@@ -51,7 +52,7 @@
     raise newException(Exception, "Unable to create swapchain")
   result.swapchain = swapchain.get()
 
-proc setupDrawableBuffers*(renderer: var Renderer, scene: Scene, inputs: seq[ShaderAttribute], transformAttribute="") =
+proc setupDrawableBuffers*(renderer: var Renderer, scene: Scene, inputs: seq[ShaderAttribute], samplers: seq[ShaderAttribute], transformAttribute="") =
   assert not (scene in renderer.scenedata)
   const VERTEX_ATTRIB_ALIGNMENT = 4 # used for buffer alignment
   var data = SceneData()
@@ -180,7 +181,17 @@
         data.textures[name] = @[]
         for texture in textures:
           data.textures[name].add renderer.device.uploadTexture(texture)
-      data.descriptorSets[pipeline.vk] = pipeline.setupDescriptors(data.uniformBuffers, data.textures, inFlightFrames=renderer.swapchain.inFlightFrames)
+          
+      var poolsizes = @[(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32(renderer.swapchain.inFlightFrames))]
+      if samplers.len > 0:
+        var samplercount = 0'u32
+        for sampler in samplers:
+          samplercount += (if sampler.arrayCount == 0: 1'u32 else: sampler.arrayCount)
+        poolsizes.add (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32(renderer.swapchain.inFlightFrames) * samplercount)
+    
+      data.descriptorPool = renderer.device.createDescriptorSetPool(poolsizes)
+  
+      data.descriptorSets[pipeline.vk] = pipeline.setupDescriptors(data.descriptorPool, data.uniformBuffers, data.textures, inFlightFrames=renderer.swapchain.inFlightFrames)
       for frame_i in 0 ..< renderer.swapchain.inFlightFrames:
         data.descriptorSets[pipeline.vk][frame_i].writeDescriptorSet()
 
@@ -295,5 +306,6 @@
     for textures in data.textures.mvalues:
       for texture in textures.mitems:
         texture.destroy()
+    data.descriptorPool.destroy()
   renderer.renderPass.destroy()
   renderer.swapchain.destroy()
--- a/src/semicongine/resources.nim	Tue May 23 18:17:15 2023 +0700
+++ b/src/semicongine/resources.nim	Wed May 24 01:30:36 2023 +0700
@@ -45,7 +45,7 @@
 
 elif thebundletype == Zip:
 
-  import zip/zipfiles
+  import zippy/ziparchives
 
   proc resourceRoot(): string =
     joinPath(absolutePath(getAppDir()), RESOURCEROOT)
@@ -53,11 +53,9 @@
     joinPath(resourceRoot(), selectedMod)
 
   proc loadResource_intern(path: string): Stream =
-    var archive: ZipArchive
-    if not archive.open(modRoot() & ".zip", fmRead):
-      raise newException(Exception, "Unable to open file " & path)
+    let archive = openZipArchive(modRoot() & ".zip")
     # read all here so we can close the stream
-    result = newStringStream(archive.getStream(path).readAll())
+    result = newStringStream(archive.extractFile(path))
     archive.close()
 
   proc modList_intern(): seq[string] =
@@ -66,10 +64,7 @@
         result.add file[0 ..< ^4]
 
   iterator walkResources_intern(): string =
-    var archive: ZipArchive
-    if not archive.open(modRoot() & ".zip", fmRead):
-      raise newException(Exception, "Unable to open file " & modRoot() & ".zip")
-
+    let archive = openZipArchive(modRoot() & ".zip")
     for i in archive.walkFiles:
       if i[^1] != '/':
         yield i
--- a/src/semicongine/resources/image.nim	Tue May 23 18:17:15 2023 +0700
+++ b/src/semicongine/resources/image.nim	Wed May 24 01:30:36 2023 +0700
@@ -105,6 +105,7 @@
 {.compile: "thirdparty/LodePNG/lodepng.c".}
 
 proc lodepng_decode32(out_data: ptr cstring, w: ptr cuint, h: ptr cuint, in_data: cstring, insize: csize_t): cuint {.importc.}
+proc free(p: pointer) {.importc.} # for some reason the lodepng pointer can only properly be freed with the native free
 
 proc readPNG*(stream: Stream): Image =
   let indata = stream.readAll()
@@ -117,6 +118,7 @@
   let imagesize = w * h * 4
   var imagedata = newSeq[Pixel](w * h)
   copyMem(addr imagedata[0], data,imagesize)
-  dealloc(data)
+
+  free(data)
 
   result = newImage(width=w, height=h, imagedata=imagedata)
--- a/src/semicongine/vulkan/pipeline.nim	Tue May 23 18:17:15 2023 +0700
+++ b/src/semicongine/vulkan/pipeline.nim	Wed May 24 01:30:36 2023 +0700
@@ -15,7 +15,6 @@
     layout*: VkPipelineLayout
     shaders*: seq[Shader]
     descriptorSetLayout*: DescriptorSetLayout
-    descriptorPool*: DescriptorPool
 
 func inputs*(pipeline: Pipeline): seq[ShaderAttribute] =
   for shader in pipeline.shaders:
@@ -32,11 +31,11 @@
         result.add attribute
         visitedUniforms[attribute.name] = attribute
 
-proc setupDescriptors*(pipeline: var Pipeline, buffers: seq[Buffer], textures: Table[string, seq[VulkanTexture]], inFlightFrames: int): seq[DescriptorSet] =
+proc setupDescriptors*(pipeline: var Pipeline, descriptorPool: DescriptorPool, buffers: seq[Buffer], textures: Table[string, seq[VulkanTexture]], inFlightFrames: int): seq[DescriptorSet] =
   assert pipeline.vk.valid
   assert buffers.len == 0 or buffers.len == inFlightFrames # need to guard against this in case we have no uniforms, then we also create no buffers
 
-  result = pipeline.descriptorPool.allocateDescriptorSet(pipeline.descriptorSetLayout, inFlightFrames)
+  result = descriptorPool.allocateDescriptorSet(pipeline.descriptorSetLayout, inFlightFrames)
   
   for i in 0 ..< inFlightFrames:
     var offset = 0'u64
@@ -193,11 +192,7 @@
     nil,
     addr(result.vk)
   )
-  var poolsizes = @[(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32(inFlightFrames))]
-  if vertexShader.samplers.len > 0:
-    poolsizes.add (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32(inFlightFrames * vertexShader.samplers.len))
 
-  result.descriptorPool = result.device.createDescriptorSetPool(poolsizes)
   discard result.uniforms # just for assertion
 
 
@@ -207,9 +202,6 @@
   assert pipeline.layout.valid
   assert pipeline.descriptorSetLayout.vk.valid
 
-  if pipeline.descriptorPool.vk.valid:
-    pipeline.descriptorPool.destroy()
-
   for shader in pipeline.shaders.mitems:
     shader.destroy()
   pipeline.descriptorSetLayout.destroy()