# HG changeset patch # User sam # Date 1684866636 -25200 # Node ID 7a7fb1a42811b9fc8d4d41f126dc2996e0eb1c3b # Parent a250ae05bbf723b7d541cc5a587c57f9d2357d86 fix: add descriptor pool per scene, use zippy instead of zip diff -r a250ae05bbf7 -r 7a7fb1a42811 src/semicongine/engine.nim --- 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 diff -r a250ae05bbf7 -r 7a7fb1a42811 src/semicongine/platform/windows/window.nim --- 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) diff -r a250ae05bbf7 -r 7a7fb1a42811 src/semicongine/renderer.nim --- 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() diff -r a250ae05bbf7 -r 7a7fb1a42811 src/semicongine/resources.nim --- 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 diff -r a250ae05bbf7 -r 7a7fb1a42811 src/semicongine/resources/image.nim --- 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) diff -r a250ae05bbf7 -r 7a7fb1a42811 src/semicongine/vulkan/pipeline.nim --- 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()