diff test1.nim @ 1190:a3eb305bcac2 compiletime-tests

start of complete and total refactoring: the ULTIMATE
author sam <sam@basx.dev>
date Sun, 07 Jul 2024 23:36:16 +0700
parents
children 239adab121a3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test1.nim	Sun Jul 07 23:36:16 2024 +0700
@@ -0,0 +1,219 @@
+import os
+
+import semicongine/rendering
+
+
+when isMainModule:
+  import semicongine/old/platform/window
+  import semicongine/old/vulkan/instance
+  import semicongine/old/vulkan/device
+  import semicongine/old/vulkan/physicaldevice
+  import std/options
+
+  type
+    MeshA = object
+      position: GPUArray[Vec3f, VertexBuffer]
+      indices: GPUArray[uint16, IndexBuffer]
+    InstanceA = object
+      rotation: GPUArray[Vec4f, VertexBuffer]
+      objPosition: GPUArray[Vec3f, VertexBuffer]
+    MaterialA = object
+      reflection: float32
+      baseColor: Vec3f
+    UniformsA = object
+      defaultTexture: Texture[TVec4[uint8]]
+      defaultMaterial: GPUValue[MaterialA, UniformBuffer]
+      materials: GPUValue[array[3, MaterialA], UniformBuffer]
+      materialTextures: array[3, Texture[TVec4[uint8]]]
+    ShaderSettings = object
+      gamma: float32
+    GlobalsA = object
+      fontAtlas: Texture[TVec4[uint8]]
+      settings: GPUValue[ShaderSettings, UniformBuffer]
+
+    ShaderA = object
+      # vertex input
+      position {.VertexAttribute.}: Vec3f
+      objPosition {.InstanceAttribute.}: Vec3f
+      rotation {.InstanceAttribute.}: Vec4f
+      # intermediate
+      test {.Pass.}: float32
+      test1 {.PassFlat.}: Vec3f
+      # output
+      color {.ShaderOutput.}: Vec4f
+      # descriptor sets
+      globals: DescriptorSet[GlobalsA, GlobalSet]
+      uniforms: DescriptorSet[UniformsA, MaterialSet]
+      # code
+      vertexCode: string = "void main() {}"
+      fragmentCode: string = "void main() {}"
+
+  let w = CreateWindow("test2")
+  putEnv("VK_LAYER_ENABLES", "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD,VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXTVK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT")
+
+  # TODO: remove those ugly wrappers
+  let theInstance = w.CreateInstance(
+    vulkanVersion = VK_MAKE_API_VERSION(0, 1, 3, 0),
+    instanceExtensions = @[],
+    layers = @["VK_LAYER_KHRONOS_validation"],
+  )
+
+  let dev = theInstance.CreateDevice(
+    theInstance.GetPhysicalDevices().FilterBestGraphics(),
+    enabledExtensions = @[],
+    theInstance.GetPhysicalDevices().FilterBestGraphics().FilterForGraphicsPresentationQueues()
+  ).vk
+  let frameWidth = 100'u32
+  let frameHeight = 100'u32
+
+  # TODO: pack this stuff into a setup method and condense everything a bit
+  let pDevice = theInstance.vk.GetPhysicalDevice()
+  let qfi = pDevice.GetQueueFamily(VK_QUEUE_GRAPHICS_BIT)
+  vulkan = VulkanGlobals(
+    instance: theInstance.vk,
+    device: dev,
+    physicalDevice: pDevice,
+    queueFamilyIndex: qfi,
+    queue: svkGetDeviceQueue(dev, qfi, VK_QUEUE_GRAPHICS_BIT)
+  )
+
+  var myMesh1 = MeshA(
+    position: GPUArray[Vec3f, VertexBuffer](data: @[NewVec3f(0, 0, ), NewVec3f(0, 0, ), NewVec3f(0, 0, )]),
+  )
+  var uniforms1 = DescriptorSet[UniformsA, MaterialSet](
+    data: UniformsA(
+      defaultTexture: Texture[TVec4[uint8]](width: 1, height: 1, data: @[TVec4[uint8]([0'u8, 0'u8, 0'u8, 1'u8])]),
+      materials: GPUValue[array[3, MaterialA], UniformBuffer](data: [
+        MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)),
+        MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)),
+        MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)),
+    ]),
+    materialTextures: [
+      Texture[TVec4[uint8]](width: 1, height: 1, data: @[TVec4[uint8]([0'u8, 0'u8, 0'u8, 1'u8])]),
+      Texture[TVec4[uint8]](width: 1, height: 1, data: @[TVec4[uint8]([0'u8, 0'u8, 0'u8, 1'u8])]),
+      Texture[TVec4[uint8]](width: 1, height: 1, data: @[TVec4[uint8]([0'u8, 0'u8, 0'u8, 1'u8])]),
+    ]
+  )
+  )
+  var instances1 = InstanceA(
+    rotation: GPUArray[Vec4f, VertexBuffer](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]),
+    objPosition: GPUArray[Vec3f, VertexBuffer](data: @[NewVec3f(0, 0, 0), NewVec3f(1, 1, 1)]),
+  )
+  var myGlobals = DescriptorSet[GlobalsA, GlobalSet](
+    data: GlobalsA(
+      fontAtlas: Texture[TVec4[uint8]](width: 1, height: 1, data: @[TVec4[uint8]([0'u8, 0'u8, 0'u8, 1'u8])]),
+      settings: GPUValue[ShaderSettings, UniformBuffer](data: ShaderSettings(gamma: 1.0))
+    )
+  )
+
+  # setup for rendering (TODO: swapchain & framebuffers)
+  let renderpass = CreateRenderPass(GetSurfaceFormat())
+
+  # shaders
+  const shader = ShaderA()
+  let shaderObject = CompileShader(shader)
+  var pipeline1 = CreatePipeline(renderPass = renderpass, shader = shaderObject)
+
+  var renderdata = InitRenderData()
+
+  # buffer assignment
+  echo "Assigning buffers to GPUData fields"
+
+  AssignBuffers(renderdata, myMesh1)
+  AssignBuffers(renderdata, instances1)
+  AssignBuffers(renderdata, myGlobals)
+  AssignBuffers(renderdata, uniforms1)
+
+  renderdata.UploadTextures(myGlobals)
+  renderdata.UploadTextures(uniforms1)
+
+  # copy everything to GPU
+  echo "Copying all data to GPU memory"
+  UpdateAllGPUBuffers(myMesh1)
+  UpdateAllGPUBuffers(instances1)
+  UpdateAllGPUBuffers(uniforms1)
+  UpdateAllGPUBuffers(myGlobals)
+  renderdata.FlushAllMemory()
+
+
+  # descriptors
+  echo "Writing descriptors"
+  InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[GlobalSet], myGlobals)
+  InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[MaterialSet], uniforms1)
+
+
+  # command buffer
+  var
+    commandBufferPool: VkCommandPool
+    createInfo = VkCommandPoolCreateInfo(
+      sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+      flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
+      queueFamilyIndex: vulkan.queueFamilyIndex,
+    )
+  checkVkResult vkCreateCommandPool(vulkan.device, addr createInfo, nil, addr commandBufferPool)
+  var
+    cmdBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer]
+    allocInfo = VkCommandBufferAllocateInfo(
+      sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+      commandPool: commandBufferPool,
+      level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+      commandBufferCount: INFLIGHTFRAMES,
+    )
+  checkVkResult vkAllocateCommandBuffers(vulkan.device, addr allocInfo, cmdBuffers.ToCPointer)
+
+  # start command buffer
+  block:
+    let
+      currentFramebuffer = VkFramebuffer(0) # TODO
+      currentFrameInFlight = 1
+      cmd = cmdBuffers[currentFrameInFlight]
+      beginInfo = VkCommandBufferBeginInfo(
+        sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+        flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
+      )
+    checkVkResult cmd.vkResetCommandBuffer(VkCommandBufferResetFlags(0))
+    checkVkResult cmd.vkBeginCommandBuffer(addr(beginInfo))
+
+    # start renderpass
+    block:
+      var
+        clearColors = [VkClearValue(color: VkClearColorValue(float32: [0, 0, 0, 0]))]
+        renderPassInfo = VkRenderPassBeginInfo(
+          sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+          renderPass: renderpass,
+          framebuffer: currentFramebuffer, # TODO
+          renderArea: VkRect2D(
+            offset: VkOffset2D(x: 0, y: 0),
+            extent: VkExtent2D(width: frameWidth, height: frameHeight),
+          ),
+          clearValueCount: uint32(clearColors.len),
+          pClearValues: clearColors.ToCPointer(),
+        )
+        viewport = VkViewport(
+          x: 0.0,
+          y: 0.0,
+          width: frameWidth.float32,
+          height: frameHeight.float32,
+          minDepth: 0.0,
+          maxDepth: 1.0,
+        )
+        scissor = VkRect2D(
+          offset: VkOffset2D(x: 0, y: 0),
+          extent: VkExtent2D(width: frameWidth, height: frameHeight)
+        )
+      vkCmdBeginRenderPass(cmd, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE)
+
+      # setup viewport
+      vkCmdSetViewport(cmd, firstViewport = 0, viewportCount = 1, addr(viewport))
+      vkCmdSetScissor(cmd, firstScissor = 0, scissorCount = 1, addr(scissor))
+
+      # bind pipeline, will be loop
+      block:
+        Bind(pipeline1, cmd, currentFrameInFlight = currentFrameInFlight)
+
+        # render object, will be loop
+        block:
+          Render(cmd, pipeline1, myGlobals, uniforms1, myMesh1, instances1)
+
+      vkCmdEndRenderPass(cmd)
+    checkVkResult cmd.vkEndCommandBuffer()