Mercurial > games > semicongine
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] = @[]