diff src/semicongine/gpu_data.nim @ 122:506090173619

did: implement uniforms, some refactoring
author Sam <sam@basx.dev>
date Sun, 09 Apr 2023 01:04:54 +0700
parents dfaddaf96f09
children 55be3579dc30
line wrap: on
line diff
--- a/src/semicongine/gpu_data.nim	Fri Apr 07 00:32:07 2023 +0700
+++ b/src/semicongine/gpu_data.nim	Sun Apr 09 01:04:54 2023 +0700
@@ -1,4 +1,3 @@
-import std/sequtils
 import std/typetraits
 import std/strformat
 import std/tables
@@ -99,24 +98,19 @@
     of Mat4F64: mat4f64: TMat4[float64]
   MemoryLocation* = enum
     VRAM, VRAMVisible, RAM # VRAM is fastest, VRAMVisible allows updating memory directly, may be slower
-  VertexAttribute* = object
+  ShaderAttribute* = object
     name*: string
     thetype*: DataType
     perInstance*: bool
     memoryLocation*: MemoryLocation
-  AttributeGroup* = object
-    attributes*: seq[VertexAttribute]
 
-func initAttributeGroup*(attrs: varargs[VertexAttribute]): auto =
-  AttributeGroup(attributes: attrs.toSeq)
-
-func vertexInputs*(group: AttributeGroup): seq[VertexAttribute] =
-  for attr in group.attributes:
+func vertexInputs*(attributes: seq[ShaderAttribute]): seq[ShaderAttribute] =
+  for attr in attributes:
     if attr.perInstance == false:
       result.add attr
 
-func instanceInputs*(group: AttributeGroup): seq[VertexAttribute] =
-  for attr in group.attributes:
+func instanceInputs*(attributes: seq[ShaderAttribute]): seq[ShaderAttribute] =
+  for attr in attributes:
     if attr.perInstance == false:
       result.add attr
 
@@ -173,12 +167,12 @@
     of Mat4F32: 64
     of Mat4F64: 128
   
-func size*(attribute: VertexAttribute, perDescriptor=false): uint32 =
+func size*(attribute: ShaderAttribute, perDescriptor=false): uint32 =
   if perDescriptor: attribute.thetype.size div attribute.thetype.numberOfVertexInputAttributeDescriptors
   else:      attribute.thetype.size
 
-func size*(thetype: AttributeGroup): uint32 =
-  for attribute in thetype.attributes:
+func size*(thetype: seq[ShaderAttribute]): uint32 =
+  for attribute in thetype:
     result += attribute.size
 
 func getDataType*[T: GPUType|int|uint|float](): DataType =
@@ -239,7 +233,7 @@
   perInstance=false,
   memoryLocation=VRAMVisible,
 ): auto =
-  VertexAttribute(
+  ShaderAttribute(
     name: name,
     thetype: getDataType[T](),
     perInstance: perInstance,
@@ -247,49 +241,150 @@
   )
 
 func get*[T: GPUType|int|uint|float](value: DataValue): T =
+  when T is float32: value.float32
+  elif T is float64: value.float64
+  elif T is int8: value.int8
+  elif T is int16: value.int16
+  elif T is int32: value.int32
+  elif T is int64: value.int64
+  elif T is uint8: value.uint8
+  elif T is uint16: value.uint16
+  elif T is uint32: value.uint32
+  elif T is uint64: value.uint64
+  elif T is int and sizeof(int) == sizeof(int32): value.int32
+  elif T is int and sizeof(int) == sizeof(int64): value.int64
+  elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32
+  elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64
+  elif T is float and sizeof(float) == sizeof(float32): value.float32
+  elif T is float and sizeof(float) == sizeof(float64): value.float64
+  elif T is TVec2[int32]: value.vec2i32
+  elif T is TVec2[int64]: value.vec2i64
+  elif T is TVec3[int32]: value.vec3i32
+  elif T is TVec3[int64]: value.vec3i64
+  elif T is TVec4[int32]: value.vec4i32
+  elif T is TVec4[int64]: value.vec4i64
+  elif T is TVec2[uint32]: value.vec2u32
+  elif T is TVec2[uint64]: value.vec2u64
+  elif T is TVec3[uint32]: value.vec3u32
+  elif T is TVec3[uint64]: value.vec3u64
+  elif T is TVec4[uint32]: value.vec4u32
+  elif T is TVec4[uint64]: value.vec4u64
+  elif T is TVec2[float32]: value.vec2f32
+  elif T is TVec2[float64]: value.vec2f64
+  elif T is TVec3[float32]: value.vec3f32
+  elif T is TVec3[float64]: value.vec3f64
+  elif T is TVec4[float32]: value.vec4f32
+  elif T is TVec4[float64]: value.vec4f64
+  elif T is TMat2[float32]: value.mat2f32
+  elif T is TMat2[float64]: value.mat2f64
+  elif T is TMat23[float32]: value.mat23f
+  elif T is TMat23[float64]: value.mat23f64
+  elif T is TMat32[float32]: value.mat32f32
+  elif T is TMat32[float64]: value.mat32f64
+  elif T is TMat3[float32]: value.mat3f32
+  elif T is TMat3[float64]: value.mat3f64
+  elif T is TMat34[float32]: value.mat34f32
+  elif T is TMat34[float64]: value.mat34f64
+  elif T is TMat43[float32]: value.mat43f32
+  elif T is TMat43[float64]: value.mat43f64
+  elif T is TMat4[float32]: value.mat4f32
+  elif T is TMat4[float64]: value.mat4f64
+
+proc getRawData*(value: var DataValue): (pointer, uint64) =
+  result[1] = value.thetype.size
   case value.thetype
-    of Float32: value.float32
-    of Float64: value.float64
-    of Int8: value.int8
-    of Int16: value.int16
-    of Int32: value.int32
-    of Int64: value.int64
-    of UInt8: value.uint8
-    of UInt16: value.uint16
-    of UInt32: value.uint32
-    of UInt64: value.uint64
-    of Vec2I32: value.vec2i32
-    of Vec2I64: value.vec2i64
-    of Vec3I32: value.vec3i32
-    of Vec3I64: value.vec3i64
-    of Vec4I32: value.vec4i32
-    of Vec4I64: value.vec4i64
-    of Vec2U32: value.vec2u32
-    of Vec2U64: value.vec2u64
-    of Vec3U32: value.vec3u32
-    of Vec3U64: value.vec3u64
-    of Vec4U32: value.vec4u32
-    of Vec4U64: value.vec4u64
-    of Vec2F32: value.vec2f32
-    of Vec2F64: value.vec2f64
-    of Vec3F32: value.vec3f32
-    of Vec3F64: value.vec3f64
-    of Vec4F32: value.vec4f32
-    of Vec4F64: value.vec4f64
-    of Mat2F32: value.mat2f32
-    of Mat2F64: value.mat2f64
-    of Mat23F32: value.mat23f32
-    of Mat23F64: value.mat23f64
-    of Mat32F32: value.mat32f32
-    of Mat32F64: value.mat32f64
-    of Mat3F32: value.mat3f32
-    of Mat3F64: value.mat3f64
-    of Mat34F32: value.mat34f32
-    of Mat34F64: value.mat34f64
-    of Mat43F32: value.mat43f32
-    of Mat43F64: value.mat43f64
-    of Mat4F32: value.mat4f32
-    of Mat4F64: value.mat4f64
+    of Float32: result[0] = addr value.float32
+    of Float64: result[0] = addr value.float64
+    of Int8: result[0] = addr value.int8
+    of Int16: result[0] = addr value.int16
+    of Int32: result[0] = addr value.int32
+    of Int64: result[0] = addr value.int64
+    of UInt8: result[0] = addr value.uint8
+    of UInt16: result[0] = addr value.uint16
+    of UInt32: result[0] = addr value.uint32
+    of UInt64: result[0] = addr value.uint64
+    of Vec2I32: result[0] = addr value.vec2i32
+    of Vec2I64: result[0] = addr value.vec2i64
+    of Vec3I32: result[0] = addr value.vec3i32
+    of Vec3I64: result[0] = addr value.vec3i64
+    of Vec4I32: result[0] = addr value.vec4i32
+    of Vec4I64: result[0] = addr value.vec4i64
+    of Vec2U32: result[0] = addr value.vec2u32
+    of Vec2U64: result[0] = addr value.vec2u64
+    of Vec3U32: result[0] = addr value.vec3u32
+    of Vec3U64: result[0] = addr value.vec3u64
+    of Vec4U32: result[0] = addr value.vec4u32
+    of Vec4U64: result[0] = addr value.vec4u64
+    of Vec2F32: result[0] = addr value.vec2f32
+    of Vec2F64: result[0] = addr value.vec2f64
+    of Vec3F32: result[0] = addr value.vec3f32
+    of Vec3F64: result[0] = addr value.vec3f64
+    of Vec4F32: result[0] = addr value.vec4f32
+    of Vec4F64: result[0] = addr value.vec4f64
+    of Mat2F32: result[0] = addr value.mat2f32
+    of Mat2F64: result[0] = addr value.mat2f64
+    of Mat23F32: result[0] = addr value.mat23f32
+    of Mat23F64: result[0] = addr value.mat23f64
+    of Mat32F32: result[0] = addr value.mat32f32
+    of Mat32F64: result[0] = addr value.mat32f64
+    of Mat3F32: result[0] = addr value.mat3f32
+    of Mat3F64: result[0] = addr value.mat3f64
+    of Mat34F32: result[0] = addr value.mat34f32
+    of Mat34F64: result[0] = addr value.mat34f64
+    of Mat43F32: result[0] = addr value.mat43f32
+    of Mat43F64: result[0] = addr value.mat43f64
+    of Mat4F32: result[0] = addr value.mat4f32
+    of Mat4F64: result[0] = addr value.mat4f64
+
+func setValue*[T: GPUType|int|uint|float](value: var DataValue, data: T) =
+  when T is float32: value.float32 = data
+  elif T is float64: value.float64 = data
+  elif T is int8: value.int8 = data
+  elif T is int16: value.int16 = data
+  elif T is int32: value.int32 = data
+  elif T is int64: value.int64 = data
+  elif T is uint8: value.uint8 = data
+  elif T is uint16: value.uint16 = data
+  elif T is uint32: value.uint32 = data
+  elif T is uint64: value.uint64 = data
+  elif T is int and sizeof(int) == sizeof(int32): value.int32 = data
+  elif T is int and sizeof(int) == sizeof(int64): value.int64 = data
+  elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32 = data
+  elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64 = data
+  elif T is float and sizeof(float) == sizeof(float32): value.float32 = data
+  elif T is float and sizeof(float) == sizeof(float64): value.float64 = data
+  elif T is TVec2[int32]: value.vec2i32 = data
+  elif T is TVec2[int64]: value.vec2i64 = data
+  elif T is TVec3[int32]: value.vec3i32 = data
+  elif T is TVec3[int64]: value.vec3i64 = data
+  elif T is TVec4[int32]: value.vec4i32 = data
+  elif T is TVec4[int64]: value.vec4i64 = data
+  elif T is TVec2[uint32]: value.vec2u32 = data
+  elif T is TVec2[uint64]: value.vec2u64 = data
+  elif T is TVec3[uint32]: value.vec3u32 = data
+  elif T is TVec3[uint64]: value.vec3u64 = data
+  elif T is TVec4[uint32]: value.vec4u32 = data
+  elif T is TVec4[uint64]: value.vec4u64 = data
+  elif T is TVec2[float32]: value.vec2f32 = data
+  elif T is TVec2[float64]: value.vec2f64 = data
+  elif T is TVec3[float32]: value.vec3f32 = data
+  elif T is TVec3[float64]: value.vec3f64 = data
+  elif T is TVec4[float32]: value.vec4f32 = data
+  elif T is TVec4[float64]: value.vec4f64 = data
+  elif T is TMat2[float32]: value.mat2f32 = data
+  elif T is TMat2[float64]: value.mat2f64 = data
+  elif T is TMat23[float32]: value.mat23f32 = data
+  elif T is TMat23[float64]: value.mat23f64 = data
+  elif T is TMat32[float32]: value.mat32f32 = data
+  elif T is TMat32[float64]: value.mat32f64 = data
+  elif T is TMat3[float32]: value.mat3f32 = data
+  elif T is TMat3[float64]: value.mat3f64 = data
+  elif T is TMat34[float32]: value.mat34f32 = data
+  elif T is TMat34[float64]: value.mat34f64 = data
+  elif T is TMat43[float32]: value.mat43f32 = data
+  elif T is TMat43[float64]: value.mat43f64 = data
+  elif T is TMat4[float32]: value.mat4f32 = data
+  elif T is TMat4[float64]: value.mat4f64 = data
 
 const TYPEMAP = {
     Float32: VK_FORMAT_R32_SFLOAT,
@@ -436,33 +531,33 @@
     of Mat4F32: "mat4"
     of Mat4F64: "dmat4"
 
-func glslInput*(group: AttributeGroup): seq[string] =
-  if group.attributes.len == 0:
+func glslInput*(group: seq[ShaderAttribute]): seq[string] =
+  if group.len == 0:
     return @[]
   var i = 0'u32
-  for attribute in group.attributes:
+  for attribute in group:
     result.add &"layout(location = {i}) in {attribute.thetype.glslType} {attribute.name};"
     for j in 0 ..< attribute.thetype.numberOfVertexInputAttributeDescriptors:
       i += attribute.thetype.nLocationSlots
 
-func glslUniforms*(group: AttributeGroup, blockName="Uniforms", binding=0): seq[string] =
-  if group.attributes.len == 0:
+func glslUniforms*(group: seq[ShaderAttribute], blockName="Uniforms", binding=0): seq[string] =
+  if group.len == 0:
     return @[]
   # currently only a single uniform block supported, therefore binding = 0
   result.add(&"layout(binding = {binding}) uniform T{blockName} {{")
-  for attribute in group.attributes:
+  for attribute in group:
     result.add(&"    {attribute.thetype.glslType} {attribute.name};")
   result.add(&"}} {blockName};")
 
-func glslOutput*(group: AttributeGroup): seq[string] =
-  if group.attributes.len == 0:
+func glslOutput*(group: seq[ShaderAttribute]): seq[string] =
+  if group.len == 0:
     return @[]
   var i = 0'u32
-  for attribute in group.attributes:
+  for attribute in group:
     result.add &"layout(location = {i}) out {attribute.thetype.glslType} {attribute.name};"
     i += 1
 
-func groupByMemoryLocation*(attributes: openArray[VertexAttribute]): Table[MemoryLocation, seq[VertexAttribute]] =
+func groupByMemoryLocation*(attributes: openArray[ShaderAttribute]): Table[MemoryLocation, seq[ShaderAttribute]] =
   for attr in attributes:
     if not (attr.memoryLocation in result):
       result[attr.memoryLocation] = @[]