# HG changeset patch # User Sam # Date 1693673462 -25200 # Node ID 43432dad4797350f8d1e4cfa44a9033c6bb4bf19 # Parent a979e5c581dec9bdd23fecdcd8189416cb64b199 did: remove some stuff from the heap, maybe nicer? diff -r a979e5c581de -r 43432dad4797 src/semicongine/core/gpu_data.nim --- a/src/semicongine/core/gpu_data.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/core/gpu_data.nim Sat Sep 02 23:51:02 2023 +0700 @@ -5,6 +5,7 @@ import ./vulkanapi import ./vector import ./matrix +import ./utils type Sampler2DType* = object @@ -101,48 +102,48 @@ DataList* = object len*: int case theType*: DataType - of Float32: float32: ref seq[float32] - of Float64: float64: ref seq[float64] - of Int8: int8: ref seq[int8] - of Int16: int16: ref seq[int16] - of Int32: int32: ref seq[int32] - of Int64: int64: ref seq[int64] - of UInt8: uint8: ref seq[uint8] - of UInt16: uint16: ref seq[uint16] - of UInt32: uint32: ref seq[uint32] - of UInt64: uint64: ref seq[uint64] - of Vec2I32: vec2i32: ref seq[TVec2[int32]] - of Vec2I64: vec2i64: ref seq[TVec2[int64]] - of Vec3I32: vec3i32: ref seq[TVec3[int32]] - of Vec3I64: vec3i64: ref seq[TVec3[int64]] - of Vec4I32: vec4i32: ref seq[TVec4[int32]] - of Vec4I64: vec4i64: ref seq[TVec4[int64]] - of Vec2U32: vec2u32: ref seq[TVec2[uint32]] - of Vec2U64: vec2u64: ref seq[TVec2[uint64]] - of Vec3U32: vec3u32: ref seq[TVec3[uint32]] - of Vec3U64: vec3u64: ref seq[TVec3[uint64]] - of Vec4U32: vec4u32: ref seq[TVec4[uint32]] - of Vec4U64: vec4u64: ref seq[TVec4[uint64]] - of Vec2F32: vec2f32: ref seq[TVec2[float32]] - of Vec2F64: vec2f64: ref seq[TVec2[float64]] - of Vec3F32: vec3f32: ref seq[TVec3[float32]] - of Vec3F64: vec3f64: ref seq[TVec3[float64]] - of Vec4F32: vec4f32: ref seq[TVec4[float32]] - of Vec4F64: vec4f64: ref seq[TVec4[float64]] - of Mat2F32: mat2f32: ref seq[TMat2[float32]] - of Mat2F64: mat2f64: ref seq[TMat2[float64]] - of Mat23F32: mat23f32: ref seq[TMat23[float32]] - of Mat23F64: mat23f64: ref seq[TMat23[float64]] - of Mat32F32: mat32f32: ref seq[TMat32[float32]] - of Mat32F64: mat32f64: ref seq[TMat32[float64]] - of Mat3F32: mat3f32: ref seq[TMat3[float32]] - of Mat3F64: mat3f64: ref seq[TMat3[float64]] - of Mat34F32: mat34f32: ref seq[TMat34[float32]] - of Mat34F64: mat34f64: ref seq[TMat34[float64]] - of Mat43F32: mat43f32: ref seq[TMat43[float32]] - of Mat43F64: mat43f64: ref seq[TMat43[float64]] - of Mat4F32: mat4f32*: ref seq[TMat4[float32]] - of Mat4F64: mat4f64: ref seq[TMat4[float64]] + of Float32: float32: seq[float32] + of Float64: float64: seq[float64] + of Int8: int8: seq[int8] + of Int16: int16: seq[int16] + of Int32: int32: seq[int32] + of Int64: int64: seq[int64] + of UInt8: uint8: seq[uint8] + of UInt16: uint16: seq[uint16] + of UInt32: uint32: seq[uint32] + of UInt64: uint64: seq[uint64] + of Vec2I32: vec2i32: seq[TVec2[int32]] + of Vec2I64: vec2i64: seq[TVec2[int64]] + of Vec3I32: vec3i32: seq[TVec3[int32]] + of Vec3I64: vec3i64: seq[TVec3[int64]] + of Vec4I32: vec4i32: seq[TVec4[int32]] + of Vec4I64: vec4i64: seq[TVec4[int64]] + of Vec2U32: vec2u32: seq[TVec2[uint32]] + of Vec2U64: vec2u64: seq[TVec2[uint64]] + of Vec3U32: vec3u32: seq[TVec3[uint32]] + of Vec3U64: vec3u64: seq[TVec3[uint64]] + of Vec4U32: vec4u32: seq[TVec4[uint32]] + of Vec4U64: vec4u64: seq[TVec4[uint64]] + of Vec2F32: vec2f32: seq[TVec2[float32]] + of Vec2F64: vec2f64: seq[TVec2[float64]] + of Vec3F32: vec3f32: seq[TVec3[float32]] + of Vec3F64: vec3f64: seq[TVec3[float64]] + of Vec4F32: vec4f32: seq[TVec4[float32]] + of Vec4F64: vec4f64: seq[TVec4[float64]] + of Mat2F32: mat2f32: seq[TMat2[float32]] + of Mat2F64: mat2f64: seq[TMat2[float64]] + of Mat23F32: mat23f32: seq[TMat23[float32]] + of Mat23F64: mat23f64: seq[TMat23[float64]] + of Mat32F32: mat32f32: seq[TMat32[float32]] + of Mat32F64: mat32f64: seq[TMat32[float64]] + of Mat3F32: mat3f32: seq[TMat3[float32]] + of Mat3F64: mat3f64: seq[TMat3[float64]] + of Mat34F32: mat34f32: seq[TMat34[float32]] + of Mat34F64: mat34f64: seq[TMat34[float64]] + of Mat43F32: mat43f32: seq[TMat43[float32]] + of Mat43F64: mat43f64: seq[TMat43[float64]] + of Mat4F32: mat4f32*: seq[TMat4[float32]] + of Mat4F64: mat4f64: seq[TMat4[float64]] of Sampler2D: discard MemoryPerformanceHint* = enum PreferFastRead, PreferFastWrite @@ -154,52 +155,6 @@ noInterpolation: bool memoryPerformanceHint*: MemoryPerformanceHint -func hash*(value: DataList): Hash = - case value.theType - of Float32: hash(cast[pointer](value.float32)) - of Float64: hash(cast[pointer](value.float64)) - of Int8: hash(cast[pointer](value.int8)) - of Int16: hash(cast[pointer](value.int16)) - of Int32: hash(cast[pointer](value.int32)) - of Int64: hash(cast[pointer](value.int64)) - of UInt8: hash(cast[pointer](value.uint8)) - of UInt16: hash(cast[pointer](value.uint16)) - of UInt32: hash(cast[pointer](value.uint32)) - of UInt64: hash(cast[pointer](value.uint64)) - of Vec2I32: hash(cast[pointer](value.vec2i32)) - of Vec2I64: hash(cast[pointer](value.vec2i64)) - of Vec3I32: hash(cast[pointer](value.vec3i32)) - of Vec3I64: hash(cast[pointer](value.vec3i64)) - of Vec4I32: hash(cast[pointer](value.vec4i32)) - of Vec4I64: hash(cast[pointer](value.vec4i64)) - of Vec2U32: hash(cast[pointer](value.vec2u32)) - of Vec2U64: hash(cast[pointer](value.vec2u64)) - of Vec3U32: hash(cast[pointer](value.vec3u32)) - of Vec3U64: hash(cast[pointer](value.vec3u64)) - of Vec4U32: hash(cast[pointer](value.vec4u32)) - of Vec4U64: hash(cast[pointer](value.vec4u64)) - of Vec2F32: hash(cast[pointer](value.vec2f32)) - of Vec2F64: hash(cast[pointer](value.vec2f64)) - of Vec3F32: hash(cast[pointer](value.vec3f32)) - of Vec3F64: hash(cast[pointer](value.vec3f64)) - of Vec4F32: hash(cast[pointer](value.vec4f32)) - of Vec4F64: hash(cast[pointer](value.vec4f64)) - of Mat2F32: hash(cast[pointer](value.mat2f32)) - of Mat2F64: hash(cast[pointer](value.mat2f64)) - of Mat23F32: hash(cast[pointer](value.mat23f32)) - of Mat23F64: hash(cast[pointer](value.mat23f64)) - of Mat32F32: hash(cast[pointer](value.mat32f32)) - of Mat32F64: hash(cast[pointer](value.mat32f64)) - of Mat3F32: hash(cast[pointer](value.mat3f32)) - of Mat3F64: hash(cast[pointer](value.mat3f64)) - of Mat34F32: hash(cast[pointer](value.mat34f32)) - of Mat34F64: hash(cast[pointer](value.mat34f64)) - of Mat43F32: hash(cast[pointer](value.mat43f32)) - of Mat43F64: hash(cast[pointer](value.mat43f64)) - of Mat4F32: hash(cast[pointer](value.mat4f32)) - of Mat4F64: hash(cast[pointer](value.mat4f64)) - of Sampler2D: raise newException(Exception, "hash not defined for Sampler2D") - func `==`*(a, b: DataList | DataValue): bool = if a.theType != b.theType: return false @@ -453,105 +408,101 @@ func setValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) = value.len = data.len - 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 + 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 else: {. error: "Virtual datatype has no values" .} -func toGPUValue*[T: GPUType](value: T): DataValue = - result = DataValue(theType: getDataType[T]()) - result.setValue(value) - func newDataList*(theType: DataType): DataList = result = DataList(theType: theType) case result.theType - of Float32: result.float32 = new seq[float32] - of Float64: result.float64 = new seq[float64] - of Int8: result.int8 = new seq[int8] - of Int16: result.int16 = new seq[int16] - of Int32: result.int32 = new seq[int32] - of Int64: result.int64 = new seq[int64] - of UInt8: result.uint8 = new seq[uint8] - of UInt16: result.uint16 = new seq[uint16] - of UInt32: result.uint32 = new seq[uint32] - of UInt64: result.uint64 = new seq[uint64] - of Vec2I32: result.vec2i32 = new seq[TVec2[int32]] - of Vec2I64: result.vec2i64 = new seq[TVec2[int64]] - of Vec3I32: result.vec3i32 = new seq[TVec3[int32]] - of Vec3I64: result.vec3i64 = new seq[TVec3[int64]] - of Vec4I32: result.vec4i32 = new seq[TVec4[int32]] - of Vec4I64: result.vec4i64 = new seq[TVec4[int64]] - of Vec2U32: result.vec2u32 = new seq[TVec2[uint32]] - of Vec2U64: result.vec2u64 = new seq[TVec2[uint64]] - of Vec3U32: result.vec3u32 = new seq[TVec3[uint32]] - of Vec3U64: result.vec3u64 = new seq[TVec3[uint64]] - of Vec4U32: result.vec4u32 = new seq[TVec4[uint32]] - of Vec4U64: result.vec4u64 = new seq[TVec4[uint64]] - of Vec2F32: result.vec2f32 = new seq[TVec2[float32]] - of Vec2F64: result.vec2f64 = new seq[TVec2[float64]] - of Vec3F32: result.vec3f32 = new seq[TVec3[float32]] - of Vec3F64: result.vec3f64 = new seq[TVec3[float64]] - of Vec4F32: result.vec4f32 = new seq[TVec4[float32]] - of Vec4F64: result.vec4f64 = new seq[TVec4[float64]] - of Mat2F32: result.mat2f32 = new seq[TMat2[float32]] - of Mat2F64: result.mat2f64 = new seq[TMat2[float64]] - of Mat23F32: result.mat23f32 = new seq[TMat23[float32]] - of Mat23F64: result.mat23f64 = new seq[TMat23[float64]] - of Mat32F32: result.mat32f32 = new seq[TMat32[float32]] - of Mat32F64: result.mat32f64 = new seq[TMat32[float64]] - of Mat3F32: result.mat3f32 = new seq[TMat3[float32]] - of Mat3F64: result.mat3f64 = new seq[TMat3[float64]] - of Mat34F32: result.mat34f32 = new seq[TMat34[float32]] - of Mat34F64: result.mat34f64 = new seq[TMat34[float64]] - of Mat43F32: result.mat43f32 = new seq[TMat43[float32]] - of Mat43F64: result.mat43f64 = new seq[TMat43[float64]] - of Mat4F32: result.mat4f32 = new seq[TMat4[float32]] - of Mat4F64: result.mat4f64 = new seq[TMat4[float64]] + of Float32: result.float32 = newSeq[float32]() + of Float64: result.float64 = newSeq[float64]() + of Int8: result.int8 = newSeq[int8]() + of Int16: result.int16 = newSeq[int16]() + of Int32: result.int32 = newSeq[int32]() + of Int64: result.int64 = newSeq[int64]() + of UInt8: result.uint8 = newSeq[uint8]() + of UInt16: result.uint16 = newSeq[uint16]() + of UInt32: result.uint32 = newSeq[uint32]() + of UInt64: result.uint64 = newSeq[uint64]() + of Vec2I32: result.vec2i32 = newSeq[TVec2[int32]]() + of Vec2I64: result.vec2i64 = newSeq[TVec2[int64]]() + of Vec3I32: result.vec3i32 = newSeq[TVec3[int32]]() + of Vec3I64: result.vec3i64 = newSeq[TVec3[int64]]() + of Vec4I32: result.vec4i32 = newSeq[TVec4[int32]]() + of Vec4I64: result.vec4i64 = newSeq[TVec4[int64]]() + of Vec2U32: result.vec2u32 = newSeq[TVec2[uint32]]() + of Vec2U64: result.vec2u64 = newSeq[TVec2[uint64]]() + of Vec3U32: result.vec3u32 = newSeq[TVec3[uint32]]() + of Vec3U64: result.vec3u64 = newSeq[TVec3[uint64]]() + of Vec4U32: result.vec4u32 = newSeq[TVec4[uint32]]() + of Vec4U64: result.vec4u64 = newSeq[TVec4[uint64]]() + of Vec2F32: result.vec2f32 = newSeq[TVec2[float32]]() + of Vec2F64: result.vec2f64 = newSeq[TVec2[float64]]() + of Vec3F32: result.vec3f32 = newSeq[TVec3[float32]]() + of Vec3F64: result.vec3f64 = newSeq[TVec3[float64]]() + of Vec4F32: result.vec4f32 = newSeq[TVec4[float32]]() + of Vec4F64: result.vec4f64 = newSeq[TVec4[float64]]() + of Mat2F32: result.mat2f32 = newSeq[TMat2[float32]]() + of Mat2F64: result.mat2f64 = newSeq[TMat2[float64]]() + of Mat23F32: result.mat23f32 = newSeq[TMat23[float32]]() + of Mat23F64: result.mat23f64 = newSeq[TMat23[float64]]() + of Mat32F32: result.mat32f32 = newSeq[TMat32[float32]]() + of Mat32F64: result.mat32f64 = newSeq[TMat32[float64]]() + of Mat3F32: result.mat3f32 = newSeq[TMat3[float32]]() + of Mat3F64: result.mat3f64 = newSeq[TMat3[float64]]() + of Mat34F32: result.mat34f32 = newSeq[TMat34[float32]]() + of Mat34F64: result.mat34f64 = newSeq[TMat34[float64]]() + of Mat43F32: result.mat43f32 = newSeq[TMat43[float32]]() + of Mat43F64: result.mat43f64 = newSeq[TMat43[float64]]() + of Mat4F32: result.mat4f32 = newSeq[TMat4[float32]]() + of Mat4F64: result.mat4f64 = newSeq[TMat4[float64]]() of Sampler2D: discard func newDataList*[T: GPUType](len=0): DataList = @@ -563,7 +514,15 @@ result = newDataList(getDataType[T]()) setValues[T](result, data) -func getValues*[T: GPUType|int|uint|float](value: DataList): ref seq[T] = +func toGPUValue*[T: GPUType](value: T): DataValue = + result = DataValue(theType: getDataType[T]()) + result.setValue(value) + +func toGPUValue*[T: GPUType](value: seq[T]): DataList = + result = newDataList[T](value.len) + result.setValue(value) + +func getValues*[T: GPUType|int|uint|float](value: DataList): seq[T] = when T is float32: value.float32 elif T is float64: value.float64 elif T is int8: value.int8 @@ -614,7 +573,58 @@ elif T is TMat4[float64]: value.mat4f64 else: {. error: "Virtual datatype has no values" .} -func getRawData*(value: DataValue): (pointer, int) = +func getValue*[T: GPUType|int|uint|float](value: DataList, i: int): T = + when T is float32: value.float32[i] + elif T is float64: value.float64[i] + elif T is int8: value.int8[i] + elif T is int16: value.int16[i] + elif T is int32: value.int32[i] + elif T is int64: value.int64[i] + elif T is uint8: value.uint8[i] + elif T is uint16: value.uint16[i] + elif T is uint32: value.uint32[i] + elif T is uint64: value.uint64[i] + elif T is int and sizeof(int) == sizeof(int32): value.int32[i] + elif T is int and sizeof(int) == sizeof(int64): value.int64[i] + elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32[i] + elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64[i] + elif T is float and sizeof(float) == sizeof(float32): value.float32[i] + elif T is float and sizeof(float) == sizeof(float64): value.float64[i] + elif T is TVec2[int32]: value.vec2i32[i] + elif T is TVec2[int64]: value.vec2i64[i] + elif T is TVec3[int32]: value.vec3i32[i] + elif T is TVec3[int64]: value.vec3i64[i] + elif T is TVec4[int32]: value.vec4i32[i] + elif T is TVec4[int64]: value.vec4i64[i] + elif T is TVec2[uint32]: value.vec2u32[i] + elif T is TVec2[uint64]: value.vec2u64[i] + elif T is TVec3[uint32]: value.vec3u32[i] + elif T is TVec3[uint64]: value.vec3u64[i] + elif T is TVec4[uint32]: value.vec4u32[i] + elif T is TVec4[uint64]: value.vec4u64[i] + elif T is TVec2[float32]: value.vec2f32[i] + elif T is TVec2[float64]: value.vec2f64[i] + elif T is TVec3[float32]: value.vec3f32[i] + elif T is TVec3[float64]: value.vec3f64[i] + elif T is TVec4[float32]: value.vec4f32[i] + elif T is TVec4[float64]: value.vec4f64[i] + elif T is TMat2[float32]: value.mat2f32[i] + elif T is TMat2[float64]: value.mat2f64[i] + elif T is TMat23[float32]: value.mat23f[i] + elif T is TMat23[float64]: value.mat23f64[i] + elif T is TMat32[float32]: value.mat32f32[i] + elif T is TMat32[float64]: value.mat32f64[i] + elif T is TMat3[float32]: value.mat3f32[i] + elif T is TMat3[float64]: value.mat3f64[i] + elif T is TMat34[float32]: value.mat34f32[i] + elif T is TMat34[float64]: value.mat34f64[i] + elif T is TMat43[float32]: value.mat43f32[i] + elif T is TMat43[float64]: value.mat43f64[i] + elif T is TMat4[float32]: value.mat4f32[i] + elif T is TMat4[float64]: value.mat4f64[i] + else: {. error: "Virtual datatype has no values" .} + +func getRawData*(value: var DataValue): (pointer, int) = result[1] = value.theType.size case value.theType of Float32: result[0] = addr value.float32 @@ -661,100 +671,100 @@ of Mat4F64: result[0] = addr value.mat4f64 of Sampler2D: result[0] = nil -func getRawData*(value: DataList): (pointer, int) = +func getRawData*(value: var DataList): (pointer, int) = if value.len == 0: return (nil, 0) result[1] = value.theType.size * value.len case value.theType - of Float32: result[0] = addr value.float32[][0] - of Float64: result[0] = addr value.float64[][0] - of Int8: result[0] = addr value.int8[][0] - of Int16: result[0] = addr value.int16[][0] - of Int32: result[0] = addr value.int32[][0] - of Int64: result[0] = addr value.int64[][0] - of UInt8: result[0] = addr value.uint8[][0] - of UInt16: result[0] = addr value.uint16[][0] - of UInt32: result[0] = addr value.uint32[][0] - of UInt64: result[0] = addr value.uint64[][0] - of Vec2I32: result[0] = addr value.vec2i32[][0] - of Vec2I64: result[0] = addr value.vec2i64[][0] - of Vec3I32: result[0] = addr value.vec3i32[][0] - of Vec3I64: result[0] = addr value.vec3i64[][0] - of Vec4I32: result[0] = addr value.vec4i32[][0] - of Vec4I64: result[0] = addr value.vec4i64[][0] - of Vec2U32: result[0] = addr value.vec2u32[][0] - of Vec2U64: result[0] = addr value.vec2u64[][0] - of Vec3U32: result[0] = addr value.vec3u32[][0] - of Vec3U64: result[0] = addr value.vec3u64[][0] - of Vec4U32: result[0] = addr value.vec4u32[][0] - of Vec4U64: result[0] = addr value.vec4u64[][0] - of Vec2F32: result[0] = addr value.vec2f32[][0] - of Vec2F64: result[0] = addr value.vec2f64[][0] - of Vec3F32: result[0] = addr value.vec3f32[][0] - of Vec3F64: result[0] = addr value.vec3f64[][0] - of Vec4F32: result[0] = addr value.vec4f32[][0] - of Vec4F64: result[0] = addr value.vec4f64[][0] - of Mat2F32: result[0] = addr value.mat2f32[][0] - of Mat2F64: result[0] = addr value.mat2f64[][0] - of Mat23F32: result[0] = addr value.mat23f32[][0] - of Mat23F64: result[0] = addr value.mat23f64[][0] - of Mat32F32: result[0] = addr value.mat32f32[][0] - of Mat32F64: result[0] = addr value.mat32f64[][0] - of Mat3F32: result[0] = addr value.mat3f32[][0] - of Mat3F64: result[0] = addr value.mat3f64[][0] - of Mat34F32: result[0] = addr value.mat34f32[][0] - of Mat34F64: result[0] = addr value.mat34f64[][0] - of Mat43F32: result[0] = addr value.mat43f32[][0] - of Mat43F64: result[0] = addr value.mat43f64[][0] - of Mat4F32: result[0] = addr value.mat4f32[][0] - of Mat4F64: result[0] = addr value.mat4f64[][0] + of Float32: result[0] = value.float32.toCPointer + of Float64: result[0] = value.float64.toCPointer + of Int8: result[0] = value.int8.toCPointer + of Int16: result[0] = value.int16.toCPointer + of Int32: result[0] = value.int32.toCPointer + of Int64: result[0] = value.int64.toCPointer + of UInt8: result[0] = value.uint8.toCPointer + of UInt16: result[0] = value.uint16.toCPointer + of UInt32: result[0] = value.uint32.toCPointer + of UInt64: result[0] = value.uint64.toCPointer + of Vec2I32: result[0] = value.vec2i32.toCPointer + of Vec2I64: result[0] = value.vec2i64.toCPointer + of Vec3I32: result[0] = value.vec3i32.toCPointer + of Vec3I64: result[0] = value.vec3i64.toCPointer + of Vec4I32: result[0] = value.vec4i32.toCPointer + of Vec4I64: result[0] = value.vec4i64.toCPointer + of Vec2U32: result[0] = value.vec2u32.toCPointer + of Vec2U64: result[0] = value.vec2u64.toCPointer + of Vec3U32: result[0] = value.vec3u32.toCPointer + of Vec3U64: result[0] = value.vec3u64.toCPointer + of Vec4U32: result[0] = value.vec4u32.toCPointer + of Vec4U64: result[0] = value.vec4u64.toCPointer + of Vec2F32: result[0] = value.vec2f32.toCPointer + of Vec2F64: result[0] = value.vec2f64.toCPointer + of Vec3F32: result[0] = value.vec3f32.toCPointer + of Vec3F64: result[0] = value.vec3f64.toCPointer + of Vec4F32: result[0] = value.vec4f32.toCPointer + of Vec4F64: result[0] = value.vec4f64.toCPointer + of Mat2F32: result[0] = value.mat2f32.toCPointer + of Mat2F64: result[0] = value.mat2f64.toCPointer + of Mat23F32: result[0] = value.mat23f32.toCPointer + of Mat23F64: result[0] = value.mat23f64.toCPointer + of Mat32F32: result[0] = value.mat32f32.toCPointer + of Mat32F64: result[0] = value.mat32f64.toCPointer + of Mat3F32: result[0] = value.mat3f32.toCPointer + of Mat3F64: result[0] = value.mat3f64.toCPointer + of Mat34F32: result[0] = value.mat34f32.toCPointer + of Mat34F64: result[0] = value.mat34f64.toCPointer + of Mat43F32: result[0] = value.mat43f32.toCPointer + of Mat43F64: result[0] = value.mat43f64.toCPointer + of Mat4F32: result[0] = value.mat4f32.toCPointer + of Mat4F64: result[0] = value.mat4f64.toCPointer of Sampler2D: result[0] = nil func initData*(value: var DataList, len: int) = value.len = len case value.theType - of Float32: value.float32[].setLen(len) - of Float64: value.float64[].setLen(len) - of Int8: value.int8[].setLen(len) - of Int16: value.int16[].setLen(len) - of Int32: value.int32[].setLen(len) - of Int64: value.int64[].setLen(len) - of UInt8: value.uint8[].setLen(len) - of UInt16: value.uint16[].setLen(len) - of UInt32: value.uint32[].setLen(len) - of UInt64: value.uint64[].setLen(len) - of Vec2I32: value.vec2i32[].setLen(len) - of Vec2I64: value.vec2i64[].setLen(len) - of Vec3I32: value.vec3i32[].setLen(len) - of Vec3I64: value.vec3i64[].setLen(len) - of Vec4I32: value.vec4i32[].setLen(len) - of Vec4I64: value.vec4i64[].setLen(len) - of Vec2U32: value.vec2u32[].setLen(len) - of Vec2U64: value.vec2u64[].setLen(len) - of Vec3U32: value.vec3u32[].setLen(len) - of Vec3U64: value.vec3u64[].setLen(len) - of Vec4U32: value.vec4u32[].setLen(len) - of Vec4U64: value.vec4u64[].setLen(len) - of Vec2F32: value.vec2f32[].setLen(len) - of Vec2F64: value.vec2f64[].setLen(len) - of Vec3F32: value.vec3f32[].setLen(len) - of Vec3F64: value.vec3f64[].setLen(len) - of Vec4F32: value.vec4f32[].setLen(len) - of Vec4F64: value.vec4f64[].setLen(len) - of Mat2F32: value.mat2f32[].setLen(len) - of Mat2F64: value.mat2f64[].setLen(len) - of Mat23F32: value.mat23f32[].setLen(len) - of Mat23F64: value.mat23f64[].setLen(len) - of Mat32F32: value.mat32f32[].setLen(len) - of Mat32F64: value.mat32f64[].setLen(len) - of Mat3F32: value.mat3f32[].setLen(len) - of Mat3F64: value.mat3f64[].setLen(len) - of Mat34F32: value.mat34f32[].setLen(len) - of Mat34F64: value.mat34f64[].setLen(len) - of Mat43F32: value.mat43f32[].setLen(len) - of Mat43F64: value.mat43f64[].setLen(len) - of Mat4F32: value.mat4f32[].setLen(len) - of Mat4F64: value.mat4f64[].setLen(len) + of Float32: value.float32.setLen(len) + of Float64: value.float64.setLen(len) + of Int8: value.int8.setLen(len) + of Int16: value.int16.setLen(len) + of Int32: value.int32.setLen(len) + of Int64: value.int64.setLen(len) + of UInt8: value.uint8.setLen(len) + of UInt16: value.uint16.setLen(len) + of UInt32: value.uint32.setLen(len) + of UInt64: value.uint64.setLen(len) + of Vec2I32: value.vec2i32.setLen(len) + of Vec2I64: value.vec2i64.setLen(len) + of Vec3I32: value.vec3i32.setLen(len) + of Vec3I64: value.vec3i64.setLen(len) + of Vec4I32: value.vec4i32.setLen(len) + of Vec4I64: value.vec4i64.setLen(len) + of Vec2U32: value.vec2u32.setLen(len) + of Vec2U64: value.vec2u64.setLen(len) + of Vec3U32: value.vec3u32.setLen(len) + of Vec3U64: value.vec3u64.setLen(len) + of Vec4U32: value.vec4u32.setLen(len) + of Vec4U64: value.vec4u64.setLen(len) + of Vec2F32: value.vec2f32.setLen(len) + of Vec2F64: value.vec2f64.setLen(len) + of Vec3F32: value.vec3f32.setLen(len) + of Vec3F64: value.vec3f64.setLen(len) + of Vec4F32: value.vec4f32.setLen(len) + of Vec4F64: value.vec4f64.setLen(len) + of Mat2F32: value.mat2f32.setLen(len) + of Mat2F64: value.mat2f64.setLen(len) + of Mat23F32: value.mat23f32.setLen(len) + of Mat23F64: value.mat23f64.setLen(len) + of Mat32F32: value.mat32f32.setLen(len) + of Mat32F64: value.mat32f64.setLen(len) + of Mat3F32: value.mat3f32.setLen(len) + of Mat3F64: value.mat3f64.setLen(len) + of Mat34F32: value.mat34f32.setLen(len) + of Mat34F64: value.mat34f64.setLen(len) + of Mat43F32: value.mat43f32.setLen(len) + of Mat43F64: value.mat43f64.setLen(len) + of Mat4F32: value.mat4f32.setLen(len) + of Mat4F64: value.mat4f64.setLen(len) of Sampler2D: discard func setValue*[T: GPUType|int|uint|float](value: var DataValue, data: T) = @@ -810,202 +820,253 @@ func appendValues*[T: GPUType|int|uint|float](value: var DataList, data: seq[T]) = value.len += data.len - when T is float32: value.float32[].add data - elif T is float64: value.float64[].add data - elif T is int8: value.int8[].add data - elif T is int16: value.int16[].add data - elif T is int32: value.int32[].add data - elif T is int64: value.int64[].add data - elif T is uint8: value.uint8[].add data - elif T is uint16: value.uint16[].add data - elif T is uint32: value.uint32[].add data - elif T is uint64: value.uint64[].add data - elif T is int and sizeof(int) == sizeof(int32): value.int32[].add data - elif T is int and sizeof(int) == sizeof(int64): value.int64[].add data - elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32[].add data - elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64[].add data - elif T is float and sizeof(float) == sizeof(float32): value.float32[].add data - elif T is float and sizeof(float) == sizeof(float64): value.float64[].add data - elif T is TVec2[int32]: value.vec2i32[].add data - elif T is TVec2[int64]: value.vec2i64[].add data - elif T is TVec3[int32]: value.vec3i32[].add data - elif T is TVec3[int64]: value.vec3i64[].add data - elif T is TVec4[int32]: value.vec4i32[].add data - elif T is TVec4[int64]: value.vec4i64[].add data - elif T is TVec2[uint32]: value.vec2u32[].add data - elif T is TVec2[uint64]: value.vec2u64[].add data - elif T is TVec3[uint32]: value.vec3u32[].add data - elif T is TVec3[uint64]: value.vec3u64[].add data - elif T is TVec4[uint32]: value.vec4u32[].add data - elif T is TVec4[uint64]: value.vec4u64[].add data - elif T is TVec2[float32]: value.vec2f32[].add data - elif T is TVec2[float64]: value.vec2f64[].add data - elif T is TVec3[float32]: value.vec3f32[].add data - elif T is TVec3[float64]: value.vec3f64[].add data - elif T is TVec4[float32]: value.vec4f32[].add data - elif T is TVec4[float64]: value.vec4f64[].add data - elif T is TMat2[float32]: value.mat2f32[].add data - elif T is TMat2[float64]: value.mat2f64[].add data - elif T is TMat23[float32]: value.mat23f32[].add data - elif T is TMat23[float64]: value.mat23f64[].add data - elif T is TMat32[float32]: value.mat32f32[].add data - elif T is TMat32[float64]: value.mat32f64[].add data - elif T is TMat3[float32]: value.mat3f32[].add data - elif T is TMat3[float64]: value.mat3f64[].add data - elif T is TMat34[float32]: value.mat34f32[].add data - elif T is TMat34[float64]: value.mat34f64[].add data - elif T is TMat43[float32]: value.mat43f32[].add data - elif T is TMat43[float64]: value.mat43f64[].add data - elif T is TMat4[float32]: value.mat4f32[].add data - elif T is TMat4[float64]: value.mat4f64[].add data + when T is float32: value.float32.add data + elif T is float64: value.float64.add data + elif T is int8: value.int8.add data + elif T is int16: value.int16.add data + elif T is int32: value.int32.add data + elif T is int64: value.int64.add data + elif T is uint8: value.uint8.add data + elif T is uint16: value.uint16.add data + elif T is uint32: value.uint32.add data + elif T is uint64: value.uint64.add data + elif T is int and sizeof(int) == sizeof(int32): value.int32.add data + elif T is int and sizeof(int) == sizeof(int64): value.int64.add data + elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32.add data + elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64.add data + elif T is float and sizeof(float) == sizeof(float32): value.float32.add data + elif T is float and sizeof(float) == sizeof(float64): value.float64.add data + elif T is TVec2[int32]: value.vec2i32.add data + elif T is TVec2[int64]: value.vec2i64.add data + elif T is TVec3[int32]: value.vec3i32.add data + elif T is TVec3[int64]: value.vec3i64.add data + elif T is TVec4[int32]: value.vec4i32.add data + elif T is TVec4[int64]: value.vec4i64.add data + elif T is TVec2[uint32]: value.vec2u32.add data + elif T is TVec2[uint64]: value.vec2u64.add data + elif T is TVec3[uint32]: value.vec3u32.add data + elif T is TVec3[uint64]: value.vec3u64.add data + elif T is TVec4[uint32]: value.vec4u32.add data + elif T is TVec4[uint64]: value.vec4u64.add data + elif T is TVec2[float32]: value.vec2f32.add data + elif T is TVec2[float64]: value.vec2f64.add data + elif T is TVec3[float32]: value.vec3f32.add data + elif T is TVec3[float64]: value.vec3f64.add data + elif T is TVec4[float32]: value.vec4f32.add data + elif T is TVec4[float64]: value.vec4f64.add data + elif T is TMat2[float32]: value.mat2f32.add data + elif T is TMat2[float64]: value.mat2f64.add data + elif T is TMat23[float32]: value.mat23f32.add data + elif T is TMat23[float64]: value.mat23f64.add data + elif T is TMat32[float32]: value.mat32f32.add data + elif T is TMat32[float64]: value.mat32f64.add data + elif T is TMat3[float32]: value.mat3f32.add data + elif T is TMat3[float64]: value.mat3f64.add data + elif T is TMat34[float32]: value.mat34f32.add data + elif T is TMat34[float64]: value.mat34f64.add data + elif T is TMat43[float32]: value.mat43f32.add data + elif T is TMat43[float64]: value.mat43f64.add data + elif T is TMat4[float32]: value.mat4f32.add data + elif T is TMat4[float64]: value.mat4f64.add data else: {. error: "Virtual datatype has no values" .} func appendValues*(value: var DataList, data: DataList) = assert value.theType == data.theType value.len += data.len case value.theType: - of Float32: value.float32[].add data.float32[] - of Float64: value.float64[].add data.float64[] - of Int8: value.int8[].add data.int8[] - of Int16: value.int16[].add data.int16[] - of Int32: value.int32[].add data.int32[] - of Int64: value.int64[].add data.int64[] - of UInt8: value.uint8[].add data.uint8[] - of UInt16: value.uint16[].add data.uint16[] - of UInt32: value.uint32[].add data.uint32[] - of UInt64: value.uint64[].add data.uint64[] - of Vec2I32: value.vec2i32[].add data.vec2i32[] - of Vec2I64: value.vec2i64[].add data.vec2i64[] - of Vec3I32: value.vec3i32[].add data.vec3i32[] - of Vec3I64: value.vec3i64[].add data.vec3i64[] - of Vec4I32: value.vec4i32[].add data.vec4i32[] - of Vec4I64: value.vec4i64[].add data.vec4i64[] - of Vec2U32: value.vec2u32[].add data.vec2u32[] - of Vec2U64: value.vec2u64[].add data.vec2u64[] - of Vec3U32: value.vec3u32[].add data.vec3u32[] - of Vec3U64: value.vec3u64[].add data.vec3u64[] - of Vec4U32: value.vec4u32[].add data.vec4u32[] - of Vec4U64: value.vec4u64[].add data.vec4u64[] - of Vec2F32: value.vec2f32[].add data.vec2f32[] - of Vec2F64: value.vec2f64[].add data.vec2f64[] - of Vec3F32: value.vec3f32[].add data.vec3f32[] - of Vec3F64: value.vec3f64[].add data.vec3f64[] - of Vec4F32: value.vec4f32[].add data.vec4f32[] - of Vec4F64: value.vec4f64[].add data.vec4f64[] - of Mat2F32: value.mat2f32[].add data.mat2f32[] - of Mat2F64: value.mat2f64[].add data.mat2f64[] - of Mat23F32: value.mat23f32[].add data.mat23f32[] - of Mat23F64: value.mat23f64[].add data.mat23f64[] - of Mat32F32: value.mat32f32[].add data.mat32f32[] - of Mat32F64: value.mat32f64[].add data.mat32f64[] - of Mat3F32: value.mat3f32[].add data.mat3f32[] - of Mat3F64: value.mat3f64[].add data.mat3f64[] - of Mat34F32: value.mat34f32[].add data.mat34f32[] - of Mat34F64: value.mat34f64[].add data.mat34f64[] - of Mat43F32: value.mat43f32[].add data.mat43f32[] - of Mat43F64: value.mat43f64[].add data.mat43f64[] - of Mat4F32: value.mat4f32[].add data.mat4f32[] - of Mat4F64: value.mat4f64[].add data.mat4f64[] + of Float32: value.float32.add data.float32 + of Float64: value.float64.add data.float64 + of Int8: value.int8.add data.int8 + of Int16: value.int16.add data.int16 + of Int32: value.int32.add data.int32 + of Int64: value.int64.add data.int64 + of UInt8: value.uint8.add data.uint8 + of UInt16: value.uint16.add data.uint16 + of UInt32: value.uint32.add data.uint32 + of UInt64: value.uint64.add data.uint64 + of Vec2I32: value.vec2i32.add data.vec2i32 + of Vec2I64: value.vec2i64.add data.vec2i64 + of Vec3I32: value.vec3i32.add data.vec3i32 + of Vec3I64: value.vec3i64.add data.vec3i64 + of Vec4I32: value.vec4i32.add data.vec4i32 + of Vec4I64: value.vec4i64.add data.vec4i64 + of Vec2U32: value.vec2u32.add data.vec2u32 + of Vec2U64: value.vec2u64.add data.vec2u64 + of Vec3U32: value.vec3u32.add data.vec3u32 + of Vec3U64: value.vec3u64.add data.vec3u64 + of Vec4U32: value.vec4u32.add data.vec4u32 + of Vec4U64: value.vec4u64.add data.vec4u64 + of Vec2F32: value.vec2f32.add data.vec2f32 + of Vec2F64: value.vec2f64.add data.vec2f64 + of Vec3F32: value.vec3f32.add data.vec3f32 + of Vec3F64: value.vec3f64.add data.vec3f64 + of Vec4F32: value.vec4f32.add data.vec4f32 + of Vec4F64: value.vec4f64.add data.vec4f64 + of Mat2F32: value.mat2f32.add data.mat2f32 + of Mat2F64: value.mat2f64.add data.mat2f64 + of Mat23F32: value.mat23f32.add data.mat23f32 + of Mat23F64: value.mat23f64.add data.mat23f64 + of Mat32F32: value.mat32f32.add data.mat32f32 + of Mat32F64: value.mat32f64.add data.mat32f64 + of Mat3F32: value.mat3f32.add data.mat3f32 + of Mat3F64: value.mat3f64.add data.mat3f64 + of Mat34F32: value.mat34f32.add data.mat34f32 + of Mat34F64: value.mat34f64.add data.mat34f64 + of Mat43F32: value.mat43f32.add data.mat43f32 + of Mat43F64: value.mat43f64.add data.mat43f64 + of Mat4F32: value.mat4f32.add data.mat4f32 + of Mat4F64: value.mat4f64.add data.mat4f64 else: raise newException(Exception, &"Unsupported data type for GPU data:" ) func appendValue*(value: var DataList, data: DataValue) = assert value.theType == data.theType, &"appendValue expected {value.theType} but got {data.theType}" value.len += 1 case value.theType: - of Float32: value.float32[].add data.float32 - of Float64: value.float64[].add data.float64 - of Int8: value.int8[].add data.int8 - of Int16: value.int16[].add data.int16 - of Int32: value.int32[].add data.int32 - of Int64: value.int64[].add data.int64 - of UInt8: value.uint8[].add data.uint8 - of UInt16: value.uint16[].add data.uint16 - of UInt32: value.uint32[].add data.uint32 - of UInt64: value.uint64[].add data.uint64 - of Vec2I32: value.vec2i32[].add data.vec2i32 - of Vec2I64: value.vec2i64[].add data.vec2i64 - of Vec3I32: value.vec3i32[].add data.vec3i32 - of Vec3I64: value.vec3i64[].add data.vec3i64 - of Vec4I32: value.vec4i32[].add data.vec4i32 - of Vec4I64: value.vec4i64[].add data.vec4i64 - of Vec2U32: value.vec2u32[].add data.vec2u32 - of Vec2U64: value.vec2u64[].add data.vec2u64 - of Vec3U32: value.vec3u32[].add data.vec3u32 - of Vec3U64: value.vec3u64[].add data.vec3u64 - of Vec4U32: value.vec4u32[].add data.vec4u32 - of Vec4U64: value.vec4u64[].add data.vec4u64 - of Vec2F32: value.vec2f32[].add data.vec2f32 - of Vec2F64: value.vec2f64[].add data.vec2f64 - of Vec3F32: value.vec3f32[].add data.vec3f32 - of Vec3F64: value.vec3f64[].add data.vec3f64 - of Vec4F32: value.vec4f32[].add data.vec4f32 - of Vec4F64: value.vec4f64[].add data.vec4f64 - of Mat2F32: value.mat2f32[].add data.mat2f32 - of Mat2F64: value.mat2f64[].add data.mat2f64 - of Mat23F32: value.mat23f32[].add data.mat23f32 - of Mat23F64: value.mat23f64[].add data.mat23f64 - of Mat32F32: value.mat32f32[].add data.mat32f32 - of Mat32F64: value.mat32f64[].add data.mat32f64 - of Mat3F32: value.mat3f32[].add data.mat3f32 - of Mat3F64: value.mat3f64[].add data.mat3f64 - of Mat34F32: value.mat34f32[].add data.mat34f32 - of Mat34F64: value.mat34f64[].add data.mat34f64 - of Mat43F32: value.mat43f32[].add data.mat43f32 - of Mat43F64: value.mat43f64[].add data.mat43f64 - of Mat4F32: value.mat4f32[].add data.mat4f32 - of Mat4F64: value.mat4f64[].add data.mat4f64 + of Float32: value.float32.add data.float32 + of Float64: value.float64.add data.float64 + of Int8: value.int8.add data.int8 + of Int16: value.int16.add data.int16 + of Int32: value.int32.add data.int32 + of Int64: value.int64.add data.int64 + of UInt8: value.uint8.add data.uint8 + of UInt16: value.uint16.add data.uint16 + of UInt32: value.uint32.add data.uint32 + of UInt64: value.uint64.add data.uint64 + of Vec2I32: value.vec2i32.add data.vec2i32 + of Vec2I64: value.vec2i64.add data.vec2i64 + of Vec3I32: value.vec3i32.add data.vec3i32 + of Vec3I64: value.vec3i64.add data.vec3i64 + of Vec4I32: value.vec4i32.add data.vec4i32 + of Vec4I64: value.vec4i64.add data.vec4i64 + of Vec2U32: value.vec2u32.add data.vec2u32 + of Vec2U64: value.vec2u64.add data.vec2u64 + of Vec3U32: value.vec3u32.add data.vec3u32 + of Vec3U64: value.vec3u64.add data.vec3u64 + of Vec4U32: value.vec4u32.add data.vec4u32 + of Vec4U64: value.vec4u64.add data.vec4u64 + of Vec2F32: value.vec2f32.add data.vec2f32 + of Vec2F64: value.vec2f64.add data.vec2f64 + of Vec3F32: value.vec3f32.add data.vec3f32 + of Vec3F64: value.vec3f64.add data.vec3f64 + of Vec4F32: value.vec4f32.add data.vec4f32 + of Vec4F64: value.vec4f64.add data.vec4f64 + of Mat2F32: value.mat2f32.add data.mat2f32 + of Mat2F64: value.mat2f64.add data.mat2f64 + of Mat23F32: value.mat23f32.add data.mat23f32 + of Mat23F64: value.mat23f64.add data.mat23f64 + of Mat32F32: value.mat32f32.add data.mat32f32 + of Mat32F64: value.mat32f64.add data.mat32f64 + of Mat3F32: value.mat3f32.add data.mat3f32 + of Mat3F64: value.mat3f64.add data.mat3f64 + of Mat34F32: value.mat34f32.add data.mat34f32 + of Mat34F64: value.mat34f64.add data.mat34f64 + of Mat43F32: value.mat43f32.add data.mat43f32 + of Mat43F64: value.mat43f64.add data.mat43f64 + of Mat4F32: value.mat4f32.add data.mat4f32 + of Mat4F64: value.mat4f64.add data.mat4f64 else: raise newException(Exception, &"Unsupported data type for GPU data:" ) +func setValue*[T: GPUType|int|uint|float](value: var DataList, data: seq[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 + else: {. error: "Virtual datatype has no values" .} + func setValue*[T: GPUType|int|uint|float](value: var DataList, i: int, data: T) = assert i < value.len - when T is float32: value.float32[][i] = data - elif T is float64: value.float64[][i] = data - elif T is int8: value.int8[][i] = data - elif T is int16: value.int16[][i] = data - elif T is int32: value.int32[][i] = data - elif T is int64: value.int64[][i] = data - elif T is uint8: value.uint8[][i] = data - elif T is uint16: value.uint16[][i] = data - elif T is uint32: value.uint32[][i] = data - elif T is uint64: value.uint64[][i] = data - elif T is int and sizeof(int) == sizeof(int32): value.int32[][i] = data - elif T is int and sizeof(int) == sizeof(int64): value.int64[][i] = data - elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32[][i] = data - elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64[][i] = data - elif T is float and sizeof(float) == sizeof(float32): value.float32[][i] = data - elif T is float and sizeof(float) == sizeof(float64): value.float64[][i] = data - elif T is TVec2[int32]: value.vec2i32[][i] = data - elif T is TVec2[int64]: value.vec2i64[][i] = data - elif T is TVec3[int32]: value.vec3i32[][i] = data - elif T is TVec3[int64]: value.vec3i64[][i] = data - elif T is TVec4[int32]: value.vec4i32[][i] = data - elif T is TVec4[int64]: value.vec4i64[][i] = data - elif T is TVec2[uint32]: value.vec2u32[][i] = data - elif T is TVec2[uint64]: value.vec2u64[][i] = data - elif T is TVec3[uint32]: value.vec3u32[][i] = data - elif T is TVec3[uint64]: value.vec3u64[][i] = data - elif T is TVec4[uint32]: value.vec4u32[][i] = data - elif T is TVec4[uint64]: value.vec4u64[][i] = data - elif T is TVec2[float32]: value.vec2f32[][i] = data - elif T is TVec2[float64]: value.vec2f64[][i] = data - elif T is TVec3[float32]: value.vec3f32[][i] = data - elif T is TVec3[float64]: value.vec3f64[][i] = data - elif T is TVec4[float32]: value.vec4f32[][i] = data - elif T is TVec4[float64]: value.vec4f64[][i] = data - elif T is TMat2[float32]: value.mat2f32[][i] = data - elif T is TMat2[float64]: value.mat2f64[][i] = data - elif T is TMat23[float32]: value.mat23f32[][i] = data - elif T is TMat23[float64]: value.mat23f64[][i] = data - elif T is TMat32[float32]: value.mat32f32[][i] = data - elif T is TMat32[float64]: value.mat32f64[][i] = data - elif T is TMat3[float32]: value.mat3f32[][i] = data - elif T is TMat3[float64]: value.mat3f64[][i] = data - elif T is TMat34[float32]: value.mat34f32[][i] = data - elif T is TMat34[float64]: value.mat34f64[][i] = data - elif T is TMat43[float32]: value.mat43f32[][i] = data - elif T is TMat43[float64]: value.mat43f64[][i] = data - elif T is TMat4[float32]: value.mat4f32[][i] = data - elif T is TMat4[float64]: value.mat4f64[][i] = data + when T is float32: value.float32[i] = data + elif T is float64: value.float64[i] = data + elif T is int8: value.int8[i] = data + elif T is int16: value.int16[i] = data + elif T is int32: value.int32[i] = data + elif T is int64: value.int64[i] = data + elif T is uint8: value.uint8[i] = data + elif T is uint16: value.uint16[i] = data + elif T is uint32: value.uint32[i] = data + elif T is uint64: value.uint64[i] = data + elif T is int and sizeof(int) == sizeof(int32): value.int32[i] = data + elif T is int and sizeof(int) == sizeof(int64): value.int64[i] = data + elif T is uint and sizeof(uint) == sizeof(uint32): value.uint32[i] = data + elif T is uint and sizeof(uint) == sizeof(uint64): value.uint64[i] = data + elif T is float and sizeof(float) == sizeof(float32): value.float32[i] = data + elif T is float and sizeof(float) == sizeof(float64): value.float64[i] = data + elif T is TVec2[int32]: value.vec2i32[i] = data + elif T is TVec2[int64]: value.vec2i64[i] = data + elif T is TVec3[int32]: value.vec3i32[i] = data + elif T is TVec3[int64]: value.vec3i64[i] = data + elif T is TVec4[int32]: value.vec4i32[i] = data + elif T is TVec4[int64]: value.vec4i64[i] = data + elif T is TVec2[uint32]: value.vec2u32[i] = data + elif T is TVec2[uint64]: value.vec2u64[i] = data + elif T is TVec3[uint32]: value.vec3u32[i] = data + elif T is TVec3[uint64]: value.vec3u64[i] = data + elif T is TVec4[uint32]: value.vec4u32[i] = data + elif T is TVec4[uint64]: value.vec4u64[i] = data + elif T is TVec2[float32]: value.vec2f32[i] = data + elif T is TVec2[float64]: value.vec2f64[i] = data + elif T is TVec3[float32]: value.vec3f32[i] = data + elif T is TVec3[float64]: value.vec3f64[i] = data + elif T is TVec4[float32]: value.vec4f32[i] = data + elif T is TVec4[float64]: value.vec4f64[i] = data + elif T is TMat2[float32]: value.mat2f32[i] = data + elif T is TMat2[float64]: value.mat2f64[i] = data + elif T is TMat23[float32]: value.mat23f32[i] = data + elif T is TMat23[float64]: value.mat23f64[i] = data + elif T is TMat32[float32]: value.mat32f32[i] = data + elif T is TMat32[float64]: value.mat32f64[i] = data + elif T is TMat3[float32]: value.mat3f32[i] = data + elif T is TMat3[float64]: value.mat3f64[i] = data + elif T is TMat34[float32]: value.mat34f32[i] = data + elif T is TMat34[float64]: value.mat34f64[i] = data + elif T is TMat43[float32]: value.mat43f32[i] = data + elif T is TMat43[float64]: value.mat43f64[i] = data + elif T is TMat4[float32]: value.mat4f32[i] = data + elif T is TMat4[float64]: value.mat4f64[i] = data else: {. error: "Virtual datatype has no values" .} const TYPEMAP = { diff -r a979e5c581de -r 43432dad4797 src/semicongine/core/utils.nim --- a/src/semicongine/core/utils.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/core/utils.nim Sat Sep 02 23:51:02 2023 +0700 @@ -8,8 +8,8 @@ result = join(str[0 ..< i]) break -func toCPointer*[T](list: var seq[T]): ptr T = - if list.len > 0: addr list[0] else: nil +func toCPointer*[T](list: seq[T]): ptr T = + if list.len > 0: addr(list[0]) else: nil proc staticExecChecked*(command: string, input = ""): string {.compileTime.} = let (output, exitcode) = gorgeEx( diff -r a979e5c581de -r 43432dad4797 src/semicongine/engine.nim --- a/src/semicongine/engine.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/engine.nim Sat Sep 02 23:51:02 2023 +0700 @@ -15,6 +15,7 @@ import ./renderer import ./events import ./audio +import ./text type EngineState* = enum @@ -105,12 +106,19 @@ proc initRenderer*(engine: var Engine, shaders: Table[string, ShaderConfiguration], clearColor=Vec4f([0.8'f32, 0.8'f32, 0.8'f32, 1'f32])) = assert not engine.renderer.isSome - engine.renderer = some(engine.device.initRenderer(shaders=shaders, clearColor=clearColor)) + var materialShaderMap = shaders + materialShaderMap[TEXT_MATERIAL] = TEXT_SHADER + engine.renderer = some(engine.device.initRenderer(shaders=materialShaderMap, clearColor=clearColor)) + +proc initRenderer*(engine: var Engine, clearColor=Vec4f([0.8'f32, 0.8'f32, 0.8'f32, 1'f32])) = + var materialShaderMap: Table[string, ShaderConfiguration] + engine.initRenderer(materialShaderMap, clearColor) proc addScene*(engine: var Engine, scene: var Scene) = assert engine.renderer.isSome engine.renderer.get.setupDrawableBuffers(scene) engine.renderer.get.updateMeshData(scene, forceAll=true) + engine.renderer.get.updateUniformData(scene, forceAll=true) proc renderScene*(engine: var Engine, scene: var Scene) = assert engine.state == Running diff -r a979e5c581de -r 43432dad4797 src/semicongine/mesh.nim --- a/src/semicongine/mesh.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/mesh.nim Sat Sep 02 23:51:02 2023 +0700 @@ -31,13 +31,11 @@ instanceData: Table[string, DataList] dirtyAttributes: seq[string] Material* = object - materialType*: string name*: string - constants*: Table[string, DataValue] + constants*: Table[string, DataList] textures*: Table[string, Texture] let EMPTY_MATERIAL = Material( - materialType: "EMPTY MATERIAL", name: "empty material" ) @@ -214,7 +212,7 @@ of Small: rawData(mesh.smallIndices) of Big: rawData(mesh.bigIndices) -func getRawData*(mesh: Mesh, attribute: string): (pointer, int) = +func getRawData*(mesh: var Mesh, attribute: string): (pointer, int) = if mesh.vertexData.contains(attribute): mesh.vertexData[attribute].getRawData() elif mesh.instanceData.contains(attribute): @@ -222,7 +220,7 @@ else: raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}") -proc getAttribute*[T: GPUType|int|uint|float](mesh: Mesh, attribute: string): ref seq[T] = +proc getAttribute*[T: GPUType|int|uint|float](mesh: Mesh, attribute: string): seq[T] = if mesh.vertexData.contains(attribute): getValues[T](mesh.vertexData[attribute]) elif mesh.instanceData.contains(attribute): @@ -294,11 +292,11 @@ proc transform*[T: GPUType](mesh: Mesh, attribute: string, transform: Mat4) = if mesh.vertexData.contains(attribute): - for v in getValues[T](mesh.vertexData[attribute])[].mitems: - v = transform * v + for i in 0 ..< mesh.vertexData[attribute].len: + setValue(mesh.vertexData[attribute], i, transform * getValue[T](mesh.vertexData[attribute], i)) elif mesh.instanceData.contains(attribute): - for v in getValues[T](mesh.instanceData[attribute])[].mitems: - v = transform * v + for i in 0 ..< mesh.instanceData[attribute].len: + setValue(mesh.instanceData[attribute], i, transform * getValue[T](mesh.vertexData[attribute], i)) else: raise newException(Exception, &"Attribute {attribute} is not defined for mesh {mesh}") @@ -351,5 +349,5 @@ result.initVertexAttribute("color", col) func getCollisionPoints*(mesh: Mesh, positionAttribute="position"): seq[Vec3f] = - for p in getAttribute[Vec3f](mesh, positionAttribute)[]: + for p in getAttribute[Vec3f](mesh, positionAttribute): result.add mesh.transform * p diff -r a979e5c581de -r 43432dad4797 src/semicongine/renderer.nim --- a/src/semicongine/renderer.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/renderer.nim Sat Sep 02 23:51:02 2023 +0700 @@ -20,8 +20,8 @@ import ./scene import ./mesh -const MATERIALINDEXATTRIBUTE = "materialIndex" const TRANSFORMATTRIBUTE = "transform" +const VERTEX_ATTRIB_ALIGNMENT = 4 # used for buffer alignment type SceneData = object @@ -43,14 +43,8 @@ scenedata: Table[Scene, SceneData] emptyTexture: VulkanTexture -func usesMaterialType(scene: Scene, materialType: string): bool = - return scene.meshes.anyIt(it.material.materialType == materialType) - -func getPipelineForMaterialtype(renderer: Renderer, materialType: string): Option[Pipeline] = - for i in 0 ..< renderer.renderPass.subpasses.len: - for pipelineMaterialType, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: - if pipelineMaterialType == materialType: - return some(pipeline) +func usesMaterial(scene: Scene, materialName: string): bool = + return scene.meshes.anyIt(it.material.name == materialName) proc initRenderer*(device: Device, shaders: Table[string, ShaderConfiguration], clearColor=Vec4f([0.8'f32, 0.8'f32, 0.8'f32, 1'f32])): Renderer = assert device.vk.valid @@ -69,82 +63,85 @@ func inputs(renderer: Renderer, scene: Scene): seq[ShaderAttribute] = var found: Table[string, ShaderAttribute] for i in 0 ..< renderer.renderPass.subpasses.len: - for materialType, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: - if scene.usesMaterialType(materialType): + for materialName, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: + if scene.usesMaterial(materialName): for input in pipeline.inputs: if found.contains(input.name): - assert input == found[input.name] + assert input == found[input.name], &"{input} != {found[input.name]}" else: result.add input found[input.name] = input func samplers(renderer: Renderer, scene: Scene): seq[ShaderAttribute] = for i in 0 ..< renderer.renderPass.subpasses.len: - for materialType, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: - if scene.usesMaterialType(materialType): + for materialName, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: + if scene.usesMaterial(materialName): result.add pipeline.samplers func materialCompatibleWithPipeline(scene: Scene, material: Material, pipeline: Pipeline): (bool, string) = for uniform in pipeline.uniforms: if scene.shaderGlobals.contains(uniform.name): if scene.shaderGlobals[uniform.name].theType != uniform.theType: - return (false, &"shader uniform needs type {uniform.theType} but scene global is of type {scene.shaderGlobals[uniform.name].theType}") + return (true, &"shader uniform needs type {uniform.theType} but scene global is of type {scene.shaderGlobals[uniform.name].theType}") else: - var foundMatch = false + var foundMatch = true for name, constant in material.constants.pairs: if name == uniform.name and constant.theType == uniform.theType: foundMatch = true break if not foundMatch: - return (false, "shader uniform '{uniform.name}' was not found in scene globals or scene materials") + return (true, &"shader uniform '{uniform.name}' was not found in scene globals or scene materials") for sampler in pipeline.samplers: - var foundMatch = false + var foundMatch = true for name, value in material.textures: if name == sampler.name: foundMatch = true break if not foundMatch: - return (false, "Required texture for shader sampler '{sampler.name}' was not found in scene materials") + return (true, &"Required texture for shader sampler '{sampler.name}' was not found in scene materials") - return (true, "") + return (false, "") func meshCompatibleWithPipeline(scene: Scene, mesh: Mesh, pipeline: Pipeline): (bool, string) = for input in pipeline.inputs: + if input.name == TRANSFORMATTRIBUTE: # will be populated automatically + continue if not (input.name in mesh.attributes): - return (false, &"Shader input '{input.name}' is not available for mesh '{mesh}'") + return (true, &"Shader input '{input.name}' is not available for mesh '{mesh}'") if input.theType != mesh.attributeType(input.name): - return (false, &"Shader input '{input.name}' expects type {input.theType}, but mesh '{mesh}' has {mesh.attributeType(input.name)}") + return (true, &"Shader input '{input.name}' expects type {input.theType}, but mesh '{mesh}' has {mesh.attributeType(input.name)}") if input.perInstance != mesh.instanceAttributes.contains(input.name): - return (false, &"Shader input '{input.name}' expects to be per instance, but mesh '{mesh}' has is not as instance attribute") + return (true, &"Shader input '{input.name}' expects to be per instance, but mesh '{mesh}' has is not as instance attribute") return materialCompatibleWithPipeline(scene, mesh.material, pipeline) func checkSceneIntegrity(renderer: Renderer, scene: Scene) = + if scene.meshes.len == 0: + return + var foundRenderableObject = false var shaderTypes: seq[string] for i in 0 ..< renderer.renderPass.subpasses.len: - for materialType, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: - shaderTypes.add materialType + for materialName, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: + shaderTypes.add materialName for mesh in scene.meshes: - if mesh.material.materialType == materialType: + if mesh.material.name == materialName: foundRenderableObject = true let (error, message) = scene.meshCompatibleWithPipeline(mesh, pipeline) if error: - raise newException(Exception, &"Mesh '{mesh}' not compatible with assigned pipeline ({materialType}) because: {message}") + raise newException(Exception, &"Mesh '{mesh}' not compatible with assigned pipeline ({materialName}) because: {message}") if not foundRenderableObject: var materialTypes: seq[string] for mesh in scene.meshes: - if not materialTypes.contains(mesh.material.materialType): - materialTypes.add mesh.material.materialType - raise newException(Exception, &"Scene {scene.name} has been added but materials are not compatible with any registered shader: Materials in scene: {materialTypes}, registered shader-materialtypes: {shaderTypes}") + if not materialTypes.contains(mesh.material.name): + materialTypes.add mesh.material.name + raise newException(Exception, &"Scene '{scene.name}' has been added but materials are not compatible with any registered shader: Materials in scene: {materialTypes}, registered shader-materialtypes: {shaderTypes}") proc setupDrawableBuffers*(renderer: var Renderer, scene: var Scene) = assert not (scene in renderer.scenedata) renderer.checkSceneIntegrity(scene) - const VERTEX_ATTRIB_ALIGNMENT = 4 # used for buffer alignment - let inputs = renderer.inputs(scene) samplers = renderer.samplers(scene) @@ -163,11 +160,6 @@ for inputAttr in inputs: if inputAttr.name == TRANSFORMATTRIBUTE: mesh.initInstanceAttribute(inputAttr.name, inputAttr.thetype) - elif inputAttr.name == MATERIALINDEXATTRIBUTE: - let matIndex = scenedata.materials.find(mesh.material) - if matIndex < 0: - raise newException(Exception, &"Required material '{mesh.material}' not available in scene (available are: {scenedata.materials})") - mesh.initInstanceAttribute(inputAttr.name, uint16(matIndex)) elif not mesh.attributes.contains(inputAttr.name): warn(&"Mesh is missing data for shader attribute {inputAttr.name}, auto-filling with empty values") if inputAttr.perInstance: @@ -222,13 +214,13 @@ preferVRAM=true, ) - # calculate offset of each attribute of all meshes + # calculate offset of each attribute for all meshes var perLocationOffsets: Table[MemoryPerformanceHint, int] var indexBufferOffset = 0 for hint in MemoryPerformanceHint: perLocationOffsets[hint] = 0 - for (meshIndex, mesh) in enumerate(scene.meshes): + for (meshIndex, mesh) in enumerate(scene.meshes.mitems): for attribute in inputs: scenedata.vertexBufferOffsets[(meshIndex, attribute.name)] = perLocationOffsets[attribute.memoryPerformanceHint] let size = mesh.getRawData(attribute.name)[1] @@ -239,8 +231,8 @@ # fill offsets per pipeline (as sequence corresponds to shader input binding) var offsets: Table[VkPipeline, seq[(string, MemoryPerformanceHint, int)]] for subpass_i in 0 ..< renderer.renderPass.subpasses.len: - for materialType, pipeline in renderer.renderPass.subpasses[subpass_i].pipelines.pairs: - if scene.usesMaterialType(materialType): + for materialName, pipeline in renderer.renderPass.subpasses[subpass_i].pipelines.pairs: + if scene.usesMaterial(materialName): offsets[pipeline.vk] = newSeq[(string, MemoryPerformanceHint, int)]() for attribute in pipeline.inputs: offsets[pipeline.vk].add (attribute.name, attribute.memoryPerformanceHint, scenedata.vertexBufferOffsets[(meshIndex, attribute.name)]) @@ -271,8 +263,8 @@ # setup uniforms and samplers for subpass_i in 0 ..< renderer.renderPass.subpasses.len: - for materialType, pipeline in renderer.renderPass.subpasses[subpass_i].pipelines.pairs: - if scene.usesMaterialType(materialType): + for materialName, pipeline in renderer.renderPass.subpasses[subpass_i].pipelines.pairs: + if scene.usesMaterial(materialName): var uniformBufferSize = 0 for uniform in pipeline.uniforms: uniformBufferSize += uniform.size @@ -307,13 +299,14 @@ renderer.scenedata[scene] = scenedata -proc refreshMeshAttributeData(renderer: Renderer, scene: Scene, drawable: Drawable, meshIndex: int, attribute: string) = +proc refreshMeshAttributeData(renderer: Renderer, scene: var Scene, drawable: Drawable, meshIndex: int, attribute: string) = debug &"Refreshing data on mesh {scene.meshes[meshIndex]} for {attribute}" # ignore attributes that are not used in this shader if not (attribute in renderer.scenedata[scene].attributeLocation): return - var (pdata, size) = scene.meshes[meshIndex].getRawData(attribute) + let (pdata, size) = scene.meshes[meshIndex].getRawData(attribute) let memoryPerformanceHint = renderer.scenedata[scene].attributeLocation[attribute] + renderer.scenedata[scene].vertexBuffers[memoryPerformanceHint].setData(pdata, size, renderer.scenedata[scene].vertexBufferOffsets[(meshIndex, attribute)]) proc updateMeshData*(renderer: var Renderer, scene: var Scene, forceAll=false) = @@ -328,25 +321,33 @@ debug &"Update mesh attribute {attribute}" scene.meshes[meshIndex].clearDirtyAttributes() -proc updateUniformData*(renderer: var Renderer, scene: var Scene) = +# TODO: only update if uniform values changed +proc updateUniformData*(renderer: var Renderer, scene: var Scene, forceAll=true) = assert scene in renderer.scenedata + # loop over all used shaders/pipelines for i in 0 ..< renderer.renderPass.subpasses.len: - for materialType, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: - if scene.usesMaterialType(materialType) and renderer.scenedata[scene].uniformBuffers.hasKey(pipeline.vk) and renderer.scenedata[scene].uniformBuffers[pipeline.vk].len != 0: + for materialName, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: + if scene.usesMaterial(materialName) and renderer.scenedata[scene].uniformBuffers.hasKey(pipeline.vk) and renderer.scenedata[scene].uniformBuffers[pipeline.vk].len != 0: assert renderer.scenedata[scene].uniformBuffers[pipeline.vk][renderer.swapchain.currentInFlight].vk.valid var offset = 0 + # loop over all uniforms of the shader for uniform in pipeline.uniforms: - var value = newDataList(thetype=uniform.thetype) + var foundValue = false + var value: DataList if scene.shaderGlobals.hasKey(uniform.name): - assert scene.shaderGlobals[uniform.name].thetype == value.thetype + assert scene.shaderGlobals[uniform.name].thetype == uniform.thetype value = scene.shaderGlobals[uniform.name] + foundValue = true else: for mat in renderer.scenedata[scene].materials: - for name, materialConstant in mat.constants.pairs: - if uniform.name == name: - value.appendValue(materialConstant) - if value.len == 0: + for name, materialConstant in mat.constants.pairs: + if uniform.name == name: + value = materialConstant + foundValue = true + break + if foundValue: break + if not foundValue: raise newException(Exception, &"Uniform '{uniform.name}' not found in scene shaderGlobals or materials") debug &"Update uniform {uniform.name}" let (pdata, size) = value.getRawData() @@ -378,14 +379,14 @@ debug " Index buffer: ", renderer.scenedata[scene].indexBuffer for i in 0 ..< renderer.renderPass.subpasses.len: - for materialType, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: - if scene.usesMaterialType(materialType): - debug &"Start pipeline for {materialType}" + for materialName, pipeline in renderer.renderPass.subpasses[i].pipelines.pairs: + if scene.usesMaterial(materialName): + debug &"Start pipeline for {materialName}" commandBuffer.vkCmdBindPipeline(renderer.renderPass.subpasses[i].pipelineBindPoint, pipeline.vk) commandBuffer.vkCmdBindDescriptorSets(renderer.renderPass.subpasses[i].pipelineBindPoint, pipeline.layout, 0, 1, addr(renderer.scenedata[scene].descriptorSets[pipeline.vk][renderer.swapchain.currentInFlight].vk), 0, nil) for (drawable, meshIndex) in renderer.scenedata[scene].drawables: - if scene.meshes[meshIndex].material.materialType == materialType: + if scene.meshes[meshIndex].material.name == materialName: drawable.draw(commandBuffer, vertexBuffers=renderer.scenedata[scene].vertexBuffers, indexBuffer=renderer.scenedata[scene].indexBuffer, pipeline.vk) if i < renderer.renderPass.subpasses.len - 1: diff -r a979e5c581de -r 43432dad4797 src/semicongine/resources/mesh.nim --- a/src/semicongine/resources/mesh.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/resources/mesh.nim Sat Sep 02 23:51:02 2023 +0700 @@ -48,7 +48,7 @@ 10497: VK_SAMPLER_ADDRESS_MODE_REPEAT }.toTable -func getGPUType(accessor: JsonNode): DataType = +proc getGPUType(accessor: JsonNode): DataType = # TODO: no full support for all datatypes that glTF may provide # semicongine/core/gpu_data should maybe generated with macros to allow for all combinations let componentType = ACCESSOR_TYPE_MAP[accessor["componentType"].getInt()] @@ -157,57 +157,57 @@ let pbr = materialNode["pbrMetallicRoughness"] # color - result.constants["baseColorFactor"] = DataValue(thetype: Vec4F32) + result.constants["baseColorFactor"] = newDataList(thetype=Vec4F32) if pbr.hasKey("baseColorFactor"): - setValue(result.constants["baseColorFactor"], newVec4f( + setValue(result.constants["baseColorFactor"], @[newVec4f( pbr["baseColorFactor"][0].getFloat(), pbr["baseColorFactor"][1].getFloat(), pbr["baseColorFactor"][2].getFloat(), pbr["baseColorFactor"][3].getFloat(), - )) + )]) else: - setValue(result.constants["baseColorFactor"], newVec4f(1, 1, 1, 1)) + setValue(result.constants["baseColorFactor"], @[newVec4f(1, 1, 1, 1)]) # pbr material constants for factor in ["metallicFactor", "roughnessFactor"]: - result.constants[factor] = DataValue(thetype: Float32) + result.constants[factor] = newDataList(thetype=Float32) if pbr.hasKey(factor): - setValue(result.constants[factor], float32(pbr[factor].getFloat())) + setValue(result.constants[factor], @[float32(pbr[factor].getFloat())]) else: - setValue(result.constants[factor], 0.5'f32) + setValue(result.constants[factor], @[0.5'f32]) # pbr material textures for texture in ["baseColorTexture", "metallicRoughnessTexture"]: if pbr.hasKey(texture): result.textures[texture] = loadTexture(root, pbr[texture]["index"].getInt(), mainBuffer) - result.constants[texture & "Index"] = DataValue(thetype: UInt8) - setValue(result.constants[texture & "Index"], pbr[texture].getOrDefault("texCoord").getInt(0).uint8) + result.constants[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.constants[texture & "Index"], @[pbr[texture].getOrDefault("texCoord").getInt(0).uint8]) else: result.textures[texture] = EMPTYTEXTURE - result.constants[texture & "Index"] = DataValue(thetype: UInt8) - setValue(result.constants[texture & "Index"], 0'u8) + result.constants[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.constants[texture & "Index"], @[0'u8]) # generic material textures for texture in ["normalTexture", "occlusionTexture", "emissiveTexture"]: if materialNode.hasKey(texture): result.textures[texture] = loadTexture(root, materialNode[texture]["index"].getInt(), mainBuffer) - result.constants[texture & "Index"] = DataValue(thetype: UInt8) - setValue(result.constants[texture & "Index"], materialNode[texture].getOrDefault("texCoord").getInt(0).uint8) + result.constants[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.constants[texture & "Index"], @[materialNode[texture].getOrDefault("texCoord").getInt(0).uint8]) else: result.textures[texture] = EMPTYTEXTURE - result.constants[texture & "Index"] = DataValue(thetype: UInt8) - setValue(result.constants[texture & "Index"], 0'u8) + result.constants[texture & "Index"] = newDataList(thetype=UInt8) + setValue(result.constants[texture & "Index"], @[0'u8]) # emissiv color - result.constants["emissiveFactor"] = DataValue(thetype: Vec3F32) + result.constants["emissiveFactor"] = newDataList(thetype=Vec3F32) if materialNode.hasKey("emissiveFactor"): - setValue(result.constants["emissiveFactor"], newVec3f( + setValue(result.constants["emissiveFactor"], @[newVec3f( materialNode["emissiveFactor"][0].getFloat(), materialNode["emissiveFactor"][1].getFloat(), materialNode["emissiveFactor"][2].getFloat(), - )) + )]) else: - setValue(result.constants["emissiveFactor"], newVec3f(1'f32, 1'f32, 1'f32)) + setValue(result.constants["emissiveFactor"], @[newVec3f(1'f32, 1'f32, 1'f32)]) proc addPrimitive(mesh: var Mesh, root: JsonNode, primitiveNode: JsonNode, mainBuffer: seq[uint8]) = @@ -236,14 +236,14 @@ var tri: seq[int] case data.thetype of UInt16: - for entry in getValues[uint16](data)[]: + for entry in getValues[uint16](data): tri.add int(entry) + baseIndex if tri.len == 3: # FYI gltf uses counter-clockwise indexing mesh.appendIndicesData(tri[0], tri[2], tri[1]) tri.setLen(0) of UInt32: - for entry in getValues[uint32](data)[]: + for entry in getValues[uint32](data): tri.add int(entry) if tri.len == 3: # FYI gltf uses counter-clockwise indexing diff -r a979e5c581de -r 43432dad4797 src/semicongine/text.nim --- a/src/semicongine/text.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/text.nim Sat Sep 02 23:51:02 2023 +0700 @@ -1,10 +1,9 @@ import std/tables import std/unicode +import ./core import ./mesh -import ./core/vector -import ./core/matrix -import ./core/fonttypes +import ./vulkan/shader type TextAlignment = enum @@ -19,6 +18,26 @@ font*: Font mesh*: Mesh +const + TEXT_MATERIAL* = "default-text" + TEXT_SHADER* = createShaderConfiguration( + inputs=[ + attr[Mat4]("transform", memoryPerformanceHint=PreferFastWrite), + attr[Vec3f]("position", memoryPerformanceHint=PreferFastWrite), + attr[Vec2f]("uv", memoryPerformanceHint=PreferFastWrite), + ], + intermediates=[attr[Vec2f]("uvFrag")], + outputs=[attr[Vec4f]("color")], + samplers=[attr[Sampler2DType]("fontAtlas")], + uniforms=[ + attr[Mat4]("perspective"), + ], + vertexCode="""gl_Position = vec4(position, 1.0) * (transform * Uniforms.perspective); uvFrag = uv;""", + # vertexCode="""gl_Position = vec4(position, 1.0);""", + fragmentCode="""color = texture(fontAtlas, uvFrag);""", + # fragmentCode="""color = vec4(1, 0, 0, 1);""", + ) + proc updateMesh(textbox: var Textbox) = # pre-calculate text-width @@ -69,7 +88,7 @@ textbox.text = text textbox.updateMesh() -proc newTextbox*(maxLen: int, font: Font, text=toRunes("")): Textbox = +proc initTextbox*(maxLen: int, font: Font, text=toRunes("")): Textbox = var positions = newSeq[Vec3f](int(maxLen * 4)) indices: seq[array[3, uint16]] @@ -83,6 +102,11 @@ result = Textbox(maxLen: maxLen, text: text, font: font, dirty: true) result.mesh = newMesh(positions = positions, indices = indices, uvs = uvs) + result.mesh.material = Material( + name: TEXT_MATERIAL, + # constants: {"glyphCoordinates": }.toTable, + textures: {"fontAtlas": font.fontAtlas}.toTable, + ) # wrap the text mesh in a new entity to preserve the font-scaling result.mesh.transform = scale(1 / font.resolution, 1 / font.resolution) diff -r a979e5c581de -r 43432dad4797 src/semicongine/vulkan/drawable.nim --- a/src/semicongine/vulkan/drawable.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/src/semicongine/vulkan/drawable.nim Sat Sep 02 23:51:02 2023 +0700 @@ -29,10 +29,14 @@ var buffers: seq[VkBuffer] var offsets: seq[VkDeviceSize] + for (name, performanceHint, offset) in drawable.bufferOffsets[pipeline]: buffers.add vertexBuffers[performanceHint].vk offsets.add VkDeviceSize(offset) + # echo "####### ", name + # echo "####### ", (cast[ptr array[4, Vec3f]](vertexBuffers[performanceHint].memory.data))[] + commandBuffer.vkCmdBindVertexBuffers( firstBinding=0'u32, bindingCount=uint32(buffers.len), diff -r a979e5c581de -r 43432dad4797 tests/test_font.nim --- a/tests/test_font.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/tests/test_font.nim Sat Sep 02 23:51:02 2023 +0700 @@ -4,48 +4,13 @@ import semicongine proc main() = - var sampler = DefaultSampler() - sampler.magnification = VK_FILTER_NEAREST - sampler.minification = VK_FILTER_NEAREST var font = loadFont("DejaVuSans.ttf", color=newVec4f(1, 0.5, 0.5, 1), resolution=20) - - var scene = newScene("main", root=newEntity("rect")) - - var flag = rect() - flag.setInstanceData("material", @[0'u8]) - # scene.root.add flag - scene.addMaterial Material(name: "material", textures: {"textures": Texture(image: loadImage("flag.png"), sampler: sampler)}.toTable) - - var textbox = newTextbox(32, font, "".toRunes) - scene.addMaterial Material(name: "fontMaterial", textures: {"textures": font.fontAtlas}.toTable) - textbox.mesh.setInstanceData("material", @[1'u8]) - textbox.transform = scale3d(0.1, 0.1) - scene.root.add textbox - - const - vertexInput = @[ - attr[Mat4]("transform", memoryPerformanceHint=PreferFastRead, perInstance=true), - attr[Vec3f]("position", memoryPerformanceHint=PreferFastRead), - attr[Vec2f]("uv", memoryPerformanceHint=PreferFastRead), - attr[uint8]("material", memoryPerformanceHint=PreferFastRead, perInstance=true), - ] - intermediate = @[attr[Vec2f]("uvout"), attr[uint8]("materialId", noInterpolation=true)] - samplers = @[attr[Sampler2DType]("textures", arrayCount=2)] - uniforms = @[attr[Mat4]("perspective")] - fragOutput = @[attr[Vec4f]("color")] - (vertexCode, fragmentCode) = compileVertexFragmentShaderSet( - inputs=vertexInput, - intermediate=intermediate, - outputs=fragOutput, - samplers=samplers, - uniforms=uniforms, - vertexCode="""gl_Position = vec4(position, 1.0) * (transform * Uniforms.perspective); uvout = uv; materialId = material;""", - fragmentCode="""color = texture(textures[materialId], uvout);""", - ) - + + var textbox = initTextbox(32, font, "".toRunes) + var scene = Scene(name: "main", meshes: @[textbox.mesh]) var engine = initEngine("Test fonts") - engine.setRenderer(engine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode)) - engine.addScene(scene, vertexInput, samplers, materialIndexAttribute="") + engine.initRenderer() + engine.addScene(scene) scene.addShaderGlobal("perspective", Unit4F32) while engine.updateInputs() == Running and not engine.keyIsDown(Escape): diff -r a979e5c581de -r 43432dad4797 tests/test_vulkan_wrapper.nim --- a/tests/test_vulkan_wrapper.nim Tue Aug 29 00:01:13 2023 +0700 +++ b/tests/test_vulkan_wrapper.nim Sat Sep 02 23:51:02 2023 +0700 @@ -13,7 +13,6 @@ (R, W) = ([255'u8, 0'u8, 0'u8, 255'u8], [255'u8, 255'u8, 255'u8, 255'u8]) mat = Material( name: "mat", - materialType: "textures_material", textures: { "my_little_texture": Texture(image: Image(width: 5, height: 5, imagedata: @[ R, R, R, R, R, @@ -26,7 +25,6 @@ ) mat2 = Material( name: "mat2", - materialType: "textures_material", textures: { "my_little_texture": Texture(image: Image(width: 5, height: 5, imagedata: @[ R, W, R, W, R, @@ -39,9 +37,8 @@ ) mat3 = Material( name: "mat3", - materialType: "plain", constants: { - "color": toGPUValue(newVec4f(0, 1, 0, 1)) + "color": toGPUValue(@[newVec4f(0, 1, 0, 1)]) }.toTable ) @@ -166,19 +163,17 @@ attr[Vec3f]("position", memoryPerformanceHint=PreferFastRead), attr[Vec4f]("color", memoryPerformanceHint=PreferFastWrite), attr[Mat4]("transform", perInstance=true), - attr[uint16]("materialIndex", perInstance=true), ], intermediates=[ attr[Vec4f]("outcolor"), - attr[uint16]("materialIndexOut", noInterpolation=true), ], outputs=[attr[Vec4f]("color")], uniforms=[attr[float32]("time")], samplers=[ - attr[Sampler2DType]("my_little_texture", arrayCount=2) + attr[Sampler2DType]("my_little_texture") ], - vertexCode="""gl_Position = vec4(position, 1.0) * transform; outcolor = color; materialIndexOut = materialIndex;""", - fragmentCode="color = texture(my_little_texture[materialIndexOut], outcolor.xy) * 0.5 + outcolor * 0.5;", + vertexCode="""gl_Position = vec4(position, 1.0) * transform; outcolor = color;""", + fragmentCode="color = texture(my_little_texture, outcolor.xy) * 0.5 + outcolor * 0.5;", ) shaderConfiguration2 = createShaderConfiguration( inputs=[ @@ -187,13 +182,14 @@ ], intermediates=[attr[Vec4f]("outcolor")], outputs=[attr[Vec4f]("color")], - uniforms=[attr[Vec4f]("color")], - vertexCode="""gl_Position = vec4(position, 1.0) * transform; outcolor = Uniforms.color;""", + uniforms=[attr[Vec4f]("color", arrayCount=1)], + vertexCode="""gl_Position = vec4(position, 1.0) * transform; outcolor = Uniforms.color[0];""", fragmentCode="color = outcolor;", ) engine.initRenderer({ - "textures_material": shaderConfiguration1, - "plain": shaderConfiguration2, + "mat": shaderConfiguration1, + "mat2": shaderConfiguration1, + "mat3": shaderConfiguration2, }.toTable) # INIT SCENES