changeset 191:81dc05b46b85

add: texture testing, not working yet, something update un-updated descritors (even though we write the descriptors man!)
author Sam <sam@basx.dev>
date Sat, 06 May 2023 01:37:33 +0700
parents 8f2eaf0d2808
children 659992f14dd6
files src/semicongine/entity.nim src/semicongine/renderer.nim src/semicongine/vulkan/image.nim src/semicongine/vulkan/pipeline.nim tests/test_vulkan_wrapper.nim
diffstat 5 files changed, 36 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/semicongine/entity.nim	Fri May 05 23:57:56 2023 +0700
+++ b/src/semicongine/entity.nim	Sat May 06 01:37:33 2023 +0700
@@ -5,7 +5,6 @@
 
 import ./math/matrix
 import ./gpu_data
-import ./vulkan/image
 
 type
   Component* = ref object of RootObj
@@ -15,7 +14,7 @@
     name*: string
     root*: Entity
     shaderGlobals*: Table[string, DataValue]
-    texture: Table[string, TextureImage]
+    textures*: Table[string, TextureImage]
 
   Entity* = ref object of RootObj
     name*: string
@@ -26,8 +25,8 @@
 
   TextureImage* = ref object of RootObj
     name*: string
-    width*: int
-    height*: int
+    width*: uint32
+    height*: uint32
     imagedata*: seq[array[4, uint8]]
 
 func addShaderGlobal*[T](scene: var Scene, name: string, data: T) =
@@ -41,7 +40,7 @@
 func setShaderGlobal*[T](scene: var Scene, name: string, value: T) =
   setValue[T](scene.shaderGlobals[name], value)
 
-func addTexture*[T](scene: var Scene, name: string, texture: Texture) =
+func addTexture*(scene: var Scene, name: string, texture: TextureImage) =
   scene.textures[name] = texture
 
 func newScene*(name: string, root: Entity): Scene =
--- a/src/semicongine/renderer.nim	Fri May 05 23:57:56 2023 +0700
+++ b/src/semicongine/renderer.nim	Sat May 06 01:37:33 2023 +0700
@@ -169,9 +169,12 @@
             requireMappable=true,
             preferVRAM=true,
           )
-      var textures: Table[string, Texture]
-      # todo: get textures from scene
-      data.textures.add textures
+      for i in 0 ..< renderer.swapchain.inFlightFrames:
+        var textures: Table[string, Texture]
+        # todo: get textures from scene, currently only 32 bit images supported
+        for name, image in scene.textures.pairs:
+          textures[name] = renderer.device.createTexture(image.width, image.height, 4, addr image.imagedata[0][0])
+        data.textures.add textures
       # need a separate descriptor for each frame in flight
       pipeline.setupDescriptors(data.uniformBuffers, data.textures, inFlightFrames=renderer.swapchain.inFlightFrames)
       pipeline.descriptorSets[i].writeDescriptorSet()
--- a/src/semicongine/vulkan/image.nim	Fri May 05 23:57:56 2023 +0700
+++ b/src/semicongine/vulkan/image.nim	Sat May 06 01:37:33 2023 +0700
@@ -29,6 +29,7 @@
     vk*: VkImageView
     image*: Image
   Texture* = object
+    image*: Image
     imageView*: ImageView
     sampler*: Sampler
 
@@ -254,13 +255,14 @@
   imageview.image.device.vk.vkDestroyImageView(imageview.vk, nil)
   imageview.vk.reset()
 
-proc createTexture*(image: Image): Texture =
-  assert image.vk.valid
-  assert image.device.vk.valid
-
-  result.imageView = image.createImageView()
-  result.sampler = image.device.createSampler()
+proc createTexture*(device: Device, width, height: uint32, depth: PixelDepth, data: pointer): Texture =
+  assert device.vk.valid
+  
+  result.image = createImage(device=device, width=width, height=width, depth=depth, data=data)
+  result.imageView = result.image.createImageView()
+  result.sampler = result.image.device.createSampler()
 
 proc destroy*(texture: var Texture) =
+  texture.image.destroy()
   texture.imageView.destroy()
   texture.sampler.destroy()
--- a/src/semicongine/vulkan/pipeline.nim	Fri May 05 23:57:56 2023 +0700
+++ b/src/semicongine/vulkan/pipeline.nim	Sat May 06 01:37:33 2023 +0700
@@ -39,10 +39,13 @@
 proc setupDescriptors*(pipeline: var Pipeline, buffers: seq[Buffer], textures: seq[Table[string, Texture]], inFlightFrames: int) =
   assert pipeline.vk.valid
   assert buffers.len == 0 or buffers.len == inFlightFrames
-  # assert textures.len == 0 or textures.len == inFlightFrames
+  assert textures.len == 0 or textures.len == inFlightFrames
+  assert pipeline.descriptorSets.len > 0
 
   for i in 0 ..< inFlightFrames:
     var offset = 0'u64
+    # first descriptor is always uniform for globals, match should be better somehow
+    assert pipeline.descriptorSets[i].layout.descriptors[0].thetype == Uniform
     for descriptor in pipeline.descriptorSets[i].layout.descriptors.mitems:
       if descriptor.thetype == Uniform:
         let size = VkDeviceSize(descriptor.itemsize * descriptor.count)
@@ -51,6 +54,8 @@
         descriptor.size = size
         offset += size
       elif descriptor.thetype == ImageSampler:
+        if not (descriptor.name in textures[i]):
+          raise newException(Exception, "Missing shader texture in scene: " & descriptor.name)
         descriptor.imageview = textures[i][descriptor.name].imageView
         descriptor.sampler = textures[i][descriptor.name].sampler
 
--- a/tests/test_vulkan_wrapper.nim	Fri May 05 23:57:56 2023 +0700
+++ b/tests/test_vulkan_wrapper.nim	Sat May 06 01:37:33 2023 +0700
@@ -117,13 +117,13 @@
     ]
     vertexOutput = @[attr[Vec3f]("outcolor")]
     uniforms = @[attr[float32]("time")]
-    # samplers = @[attr[Sampler2DType]("my_little_texture")]
+    samplers = @[attr[Sampler2DType]("my_little_texture")]
     fragOutput = @[attr[Vec4f]("color")]
     vertexCode = compileGlslShader(
       stage=VK_SHADER_STAGE_VERTEX_BIT,
       inputs=vertexInput,
       uniforms=uniforms,
-      # samplers=samplers,
+      samplers=samplers,
       outputs=vertexOutput,
       main="""gl_Position = vec4(position + translate, 1.0); outcolor = color;"""
     )
@@ -131,10 +131,9 @@
       stage=VK_SHADER_STAGE_FRAGMENT_BIT,
       inputs=vertexOutput,
       uniforms=uniforms,
-      # samplers=samplers,
+      samplers=samplers,
       outputs=fragOutput,
-      # main="color = texture(my_little_texture, outcolor.xy) * 0.5 + vec4(outcolor, 1) * 0.5;"
-      main="color = vec4(outcolor, 1) * 0.5;"
+      main="color = texture(my_little_texture, outcolor.xy) * 0.5 + vec4(outcolor, 1) * 0.5;"
     )
   var renderPass = engine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode)
   engine.setRenderer(renderPass)
@@ -147,6 +146,14 @@
   ]
   for scene in scenes.mitems:
     scene.addShaderGlobal("time", 0.0'f32)
+    let (R, W) = ([0'u8, 0'u8, 0'u8, 0'u8], [0'u8, 0'u8, 0'u8, 0'u8])
+    scene.addTexture("my_little_texture", TextureImage(width: 5, height: 5, imagedata: @[
+      R, R, R, R, R,
+      R, R, R, R, R,
+      R, R, R, R, R,
+      R, R, R, R, R,
+      R, R, R, R, R,
+    ]))
     engine.addScene(scene, vertexInput)
 
   # MAINLOOP