changeset 1172:2e0b527c2753 compiletime-tests

merge?
author sam <sam@basx.dev>
date Thu, 27 Jun 2024 20:52:50 +0700
parents dc6e1660831d
children fafc2f14da0b 26e367076c15
files config.nims semicongine/core/buildconfig.nim semicongine/core/imagetypes.nim semicongine/mesh.nim semicongine/renderer.nim semicongine/vulkan/descriptor.nim static_utils.nim
diffstat 7 files changed, 115 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/config.nims	Wed Jun 26 17:46:36 2024 +0700
+++ b/config.nims	Thu Jun 27 20:52:50 2024 +0700
@@ -7,6 +7,7 @@
 # TODO: totally update this file!!
 
 switch("nimblePath", "nimbledeps/pkgs2")
+switch("define", "nimPreviewHashRef")
 
 task build_dev, "build dev":
   semicongine_build_switches(buildname = "dev")
--- a/semicongine/core/buildconfig.nim	Wed Jun 26 17:46:36 2024 +0700
+++ b/semicongine/core/buildconfig.nim	Thu Jun 27 20:52:50 2024 +0700
@@ -46,6 +46,6 @@
 const ENGINE_LOGLEVEL* = parseEnum[Level]("lvl" & LOGLEVEL)
 
 # resource bundleing settings, need to be configured per project
-const PACKAGETYPE* {.strdefine.}: string = "" # dir, zip, exe
+const PACKAGETYPE* {.strdefine.}: string = "exe" # dir, zip, exe
 static:
   assert PACKAGETYPE in ["dir", "zip", "exe"], ENGINENAME & " requires one of -d:PACKAGETYPE=dir -d:PACKAGETYPE=zip -d:PACKAGETYPE=exe"
--- a/semicongine/core/imagetypes.nim	Wed Jun 26 17:46:36 2024 +0700
+++ b/semicongine/core/imagetypes.nim	Thu Jun 27 20:52:50 2024 +0700
@@ -8,12 +8,11 @@
   RGBAPixel* = array[4, uint8]
   GrayPixel* = uint8
   Pixel* = RGBAPixel or GrayPixel
-  # ImageObject*[T: Pixel] = object
-  Image*[T: Pixel] = object
+  ImageObject*[T: Pixel] = object
     width*: uint32
     height*: uint32
     imagedata*: seq[T]
-  # Image*[T: Pixel] = ref ImageObject[T]
+  Image*[T: Pixel] = ref ImageObject[T]
 
   Sampler* = object
     magnification*: VkFilter = VK_FILTER_LINEAR
@@ -82,6 +81,7 @@
   assert width > 0 and height > 0
   assert imagedata.len.uint32 == width * height or imagedata.len == 0
 
+  result = new Image[T]
   result.imagedata = (if imagedata.len == 0: newSeq[T](width * height) else: @imagedata)
   assert width * height == result.imagedata.len.uint32
 
--- a/semicongine/mesh.nim	Wed Jun 26 17:46:36 2024 +0700
+++ b/semicongine/mesh.nim	Thu Jun 27 20:52:50 2024 +0700
@@ -18,6 +18,7 @@
 type
   MeshIndexType* = enum
     None
+    Tiny  # up to 2^8 vertices # TODO: need to check and enable support for this
     Small # up to 2^16 vertices
     Big   # up to 2^32 vertices
   MeshObject* = object
@@ -25,6 +26,7 @@
     vertexCount*: int
     case indexType*: MeshIndexType
       of None: discard
+      of Tiny: tinyIndices*: seq[array[3, uint8]]
       of Small: smallIndices*: seq[array[3, uint16]]
       of Big: bigIndices*: seq[array[3, uint32]]
     material*: MaterialData
@@ -63,6 +65,7 @@
   (
     case mesh.indexType
     of None: 0
+    of Tiny: mesh.tinyIndices.len
     of Small: mesh.smallIndices.len
     of Big: mesh.bigIndices.len
   ) * 3
@@ -90,6 +93,7 @@
 converter ToVulkan*(indexType: MeshIndexType): VkIndexType =
   case indexType:
     of None: VK_INDEX_TYPE_NONE_KHR
+    of Tiny: VK_INDEX_TYPE_UINT8_EXT
     of Small: VK_INDEX_TYPE_UINT16
     of Big: VK_INDEX_TYPE_UINT32
 
@@ -150,7 +154,9 @@
   var indexType = None
   if indices.len > 0:
     indexType = Big
-    if autoResize and uint32(positions.len) < uint32(high(uint16)):
+    if autoResize and uint32(positions.len) < uint32(high(uint8)) and false: # TODO: check feature support
+      indexType = Tiny
+    elif autoResize and uint32(positions.len) < uint32(high(uint16)):
       indexType = Small
 
   result = Mesh(
@@ -172,7 +178,10 @@
     assert int(i[2]) < result[].vertexCount
 
   # cast index values to appropiate type
-  if result[].indexType == Small and uint32(positions.len) < uint32(high(uint16)):
+  if result[].indexType == Tiny and uint32(positions.len) < uint32(high(uint8)) and false: # TODO: check feature support
+    for i, tri in enumerate(indices):
+      result[].tinyIndices.add [uint8(tri[0]), uint8(tri[1]), uint8(tri[2])]
+  elif result[].indexType == Small and uint32(positions.len) < uint32(high(uint16)):
     for i, tri in enumerate(indices):
       result[].smallIndices.add [uint16(tri[0]), uint16(tri[1]), uint16(tri[2])]
   elif result[].indexType == Big:
@@ -219,6 +228,7 @@
 func IndexSize*(mesh: MeshObject): uint64 =
   case mesh.indexType
     of None: 0'u64
+    of Tiny: uint64(mesh.tinyIndices.len * sizeof(get(genericParams(typeof(mesh.tinyIndices)), 0)))
     of Small: uint64(mesh.smallIndices.len * sizeof(get(genericParams(typeof(mesh.smallIndices)), 0)))
     of Big: uint64(mesh.bigIndices.len * sizeof(get(genericParams(typeof(mesh.bigIndices)), 0)))
 
@@ -231,6 +241,7 @@
 func GetRawIndexData*(mesh: MeshObject): (pointer, uint64) =
   case mesh.indexType:
     of None: raise newException(Exception, "Trying to get index data for non-indexed mesh")
+    of Tiny: rawData(mesh.tinyIndices)
     of Small: rawData(mesh.smallIndices)
     of Big: rawData(mesh.bigIndices)
 
@@ -341,6 +352,7 @@
 proc AppendIndicesData*(mesh: var MeshObject, v1, v2, v3: int) =
   case mesh.indexType
   of None: raise newException(Exception, "Mesh does not support indexed data")
+  of Tiny: mesh.tinyIndices.add([uint8(v1), uint8(v2), uint8(v3)])
   of Small: mesh.smallIndices.add([uint16(v1), uint16(v2), uint16(v3)])
   of Big: mesh.bigIndices.add([uint32(v1), uint32(v2), uint32(v3)])
 
@@ -412,6 +424,13 @@
     result.instanceData[attribute] = datalist.Copy()
   var i = 0
   case mesh.indexType
+  of Tiny:
+    for indices in mesh.tinyIndices:
+      for attribute, value in mesh.vertexData.pairs:
+        result.vertexData[attribute].AppendFrom(i, mesh.vertexData[attribute], int(indices[0]))
+        result.vertexData[attribute].AppendFrom(i + 1, mesh.vertexData[attribute], int(indices[1]))
+        result.vertexData[attribute].AppendFrom(i + 2, mesh.vertexData[attribute], int(indices[2]))
+      i += 3
   of Small:
     for indices in mesh.smallIndices:
       for attribute, value in mesh.vertexData.pairs:
@@ -567,6 +586,10 @@
   case a.indexType:
     of None:
       discard
+    of Tiny:
+      let offset = uint8(originalOffset)
+      for i in b.tinyIndices:
+        a.tinyIndices.add [i[0] + offset, i[1] + offset, i[2] + offset]
     of Small:
       let offset = uint16(originalOffset)
       for i in b.smallIndices:
--- a/semicongine/renderer.nim	Wed Jun 26 17:46:36 2024 +0700
+++ b/semicongine/renderer.nim	Thu Jun 27 20:52:50 2024 +0700
@@ -132,6 +132,7 @@
     if mesh[].indexType != MeshIndexType.None:
       let indexAlignment = case mesh[].indexType
         of MeshIndexType.None: 0'u64
+        of Tiny: 1'u64
         of Small: 2'u64
         of Big: 4'u64
       # index value alignment required by Vulkan
@@ -211,6 +212,7 @@
     if indexed:
       let indexAlignment = case mesh.indexType
         of MeshIndexType.None: 0'u64
+        of Tiny: 1'u64
         of Small: 2'u64
         of Big: 4'u64
       # index value alignment required by Vulkan
--- a/semicongine/vulkan/descriptor.nim	Wed Jun 26 17:46:36 2024 +0700
+++ b/semicongine/vulkan/descriptor.nim	Thu Jun 27 20:52:50 2024 +0700
@@ -106,6 +106,7 @@
   assert layout.vk.Valid
 
   var layouts: seq[VkDescriptorSetLayout]
+  var descriptorSets = newSeq[VkDescriptorSet](nframes)
   for i in 0 ..< nframes:
     layouts.add layout.vk
   var allocInfo = VkDescriptorSetAllocateInfo(
@@ -115,7 +116,6 @@
     pSetLayouts: layouts.ToCPointer,
   )
 
-  var descriptorSets = newSeq[VkDescriptorSet](nframes)
   checkVkResult vkAllocateDescriptorSets(pool.device.vk, addr(allocInfo), descriptorSets.ToCPointer)
   for descriptorSet in descriptorSets:
     result.add DescriptorSet(vk: descriptorSet, layout: layout)
--- a/static_utils.nim	Wed Jun 26 17:46:36 2024 +0700
+++ b/static_utils.nim	Thu Jun 27 20:52:50 2024 +0700
@@ -216,6 +216,63 @@
     of UInt16: VK_INDEX_TYPE_UINT16
     of UInt32: VK_INDEX_TYPE_UINT32
 
+proc CreateRenderPass*(
+  device: VkDevice,
+  format: VkFormat,
+): VkRenderPass =
+
+  var
+    attachments = @[VkAttachmentDescription(
+        format: format,
+        samples: VK_SAMPLE_COUNT_1_BIT,
+        loadOp: VK_ATTACHMENT_LOAD_OP_CLEAR,
+        storeOp: VK_ATTACHMENT_STORE_OP_STORE,
+        stencilLoadOp: VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        stencilStoreOp: VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        initialLayout: VK_IMAGE_LAYOUT_UNDEFINED,
+        finalLayout: VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+    )]
+    dependencies = @[VkSubpassDependency(
+      srcSubpass: VK_SUBPASS_EXTERNAL,
+      dstSubpass: 0,
+      srcStageMask: toBits [VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT],
+      srcAccessMask: toBits [VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT],
+      dstStageMask: toBits [VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT],
+      dstAccessMask: toBits [VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT],
+    )]
+    outputs = @[
+      VkAttachmentReference(
+        attachment: 0,
+        layout: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+      )
+    ]
+
+  var subpassesList = [
+    VkSubpassDescription(
+      flags: VkSubpassDescriptionFlags(0),
+      pipelineBindPoint: VK_PIPELINE_BIND_POINT_GRAPHICS,
+      inputAttachmentCount: 0,
+      pInputAttachments: nil,
+      colorAttachmentCount: uint32(outputs.len),
+      pColorAttachments: outputs.ToCPointer,
+      pResolveAttachments: nil,
+      pDepthStencilAttachment: nil,
+      preserveAttachmentCount: 0,
+      pPreserveAttachments: nil,
+    )
+  ]
+
+  var createInfo = VkRenderPassCreateInfo(
+      sType: VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+      attachmentCount: uint32(attachments.len),
+      pAttachments: attachments.ToCPointer,
+      subpassCount: uint32(subpassesList.len),
+      pSubpasses: subpassesList.ToCPointer,
+      dependencyCount: uint32(dependencies.len),
+      pDependencies: dependencies.ToCPointer,
+    )
+  checkVkResult device.vkCreateRenderPass(addr(createInfo), nil, addr(result))
+
 proc compileGlslToSPIRV(stage: VkShaderStageFlagBits, shaderSource: string): seq[uint32] {.compileTime.} =
   func stage2string(stage: VkShaderStageFlagBits): string {.compileTime.} =
     case stage
@@ -553,25 +610,27 @@
 
   # write descriptor sets
   # TODO
+  #[
   var descriptorSetWrites: seq[VkWriteDescriptorSet]
   for XY in descriptors?:
 
-      bufferInfos.add VkDescriptorBufferInfo(
-        buffer: descriptor.buffer.vk,
-        offset: descriptor.offset,
-        range: descriptor.size,
-      )
-      descriptorSetWrites.add VkWriteDescriptorSet(
-          sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
-          dstSet: descriptorSet.vk,
-          dstBinding: i,
-          dstArrayElement: 0,
-          descriptorType: descriptor.vkType,
-          descriptorCount: uint32(descriptor.count),
-          pBufferInfo: addr bufferInfos[^1],
-        )
+    bufferInfos.add VkDescriptorBufferInfo(
+      buffer: descriptor.buffer.vk,
+      offset: descriptor.offset,
+      range: descriptor.size,
+    )
+    descriptorSetWrites.add VkWriteDescriptorSet(
+      sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+      dstSet: descriptorSet.vk,
+      dstBinding: i,
+      dstArrayElement: 0,
+      descriptorType: descriptor.vkType,
+      descriptorCount: uint32(descriptor.count),
+      pBufferInfo: addr bufferInfos[^1],
+    )
+    vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil)
+  ]#
 
-  vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil)
 
 proc CreateRenderable[TMesh, TInstance](
   mesh: TMesh,
@@ -580,9 +639,11 @@
 ): Renderable[TMesh, TInstance] =
   result.indexType = None
 
-proc Bind(pipeline: Pipeline, commandBuffer: VkCommandBuffer, currentFrameInFlight: int) =
+proc Bind[T](pipeline: Pipeline[T], commandBuffer: VkCommandBuffer, currentFrameInFlight: int) =
+  let a = pipeline.descriptorSets
+  echo a[^currentFrameInFlight]
   commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline)
-  if pipeline.descriptorSets[currentFrameInFlight] != VkDescriptorSet(0):
+  if a[currentFrameInFlight] != VkDescriptorSet(0):
     commandBuffer.vkCmdBindDescriptorSets(
       VK_PIPELINE_BIND_POINT_GRAPHICS,
       pipeline.layout,
@@ -682,7 +743,7 @@
   import semicongine/vulkan/instance
   import semicongine/vulkan/device
   import semicongine/vulkan/physicaldevice
-  import semicongine/vulkan/renderpass
+  # import semicongine/vulkan/renderpass
   import semicongine/vulkan/commandbuffer
   import std/options
 
@@ -747,7 +808,7 @@
   let rp = d.vk.CreateRenderPass(d.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat().format)
   var p = CreatePipeline(d.vk, renderPass = rp, shaderObject)
 
-  let commandBufferPool = d.CreateCommandBufferPool(d.FirstGraphicsQueue().get().family, INFLIGHTFRAMES)
+  let commandBufferPool = d.CreateCommandBufferPool(d.FirstGraphicsQueue().get().family, INFLIGHTFRAMES.int)
   let cmd = commandBufferPool.buffers[0]
 
   checkVkResult cmd.vkResetCommandBuffer(VkCommandBufferResetFlags(0))
@@ -756,7 +817,7 @@
     flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
   )
   checkVkResult cmd.vkBeginCommandBuffer(addr(beginInfo))
-  p.Bind(cmd, currentFrameInFlight = 0)
-  p.Render(r, g, cmd)
+  Bind(p, cmd, currentFrameInFlight = 0)
+  Render(p, r, g, cmd)
 
   checkVkResult cmd.vkEndCommandBuffer()