# HG changeset patch # User sam # Date 1720253128 -25200 # Node ID 565fcfde427ab4fe2e36a27b36e51bea2b7df731 # Parent 3f43c7163029e60ab1283c42593c05473df74080 did: first seemingly working version of texture/descriptor stuff diff -r 3f43c7163029 -r 565fcfde427a semicongine/core/vector.nim --- a/semicongine/core/vector.nim Sat Jul 06 00:31:17 2024 +0700 +++ b/semicongine/core/vector.nim Sat Jul 06 15:05:28 2024 +0700 @@ -9,20 +9,26 @@ import ./vulkanapi type + TVec1*[T: SomeNumber] = array[1, T] TVec2*[T: SomeNumber] = array[2, T] TVec3*[T: SomeNumber] = array[3, T] TVec4*[T: SomeNumber] = array[4, T] - TVec* = TVec2|TVec3|TVec4 + TVec* = TVec1|TVec2|TVec3|TVec4 + Vec1f* = TVec1[float32] Vec2f* = TVec2[float32] Vec3f* = TVec3[float32] Vec4f* = TVec4[float32] + Vec1i* = TVec1[int32] Vec2i* = TVec2[int32] Vec3i* = TVec3[int32] Vec4i* = TVec4[int32] + Vec1u* = TVec1[uint32] Vec2u* = TVec2[uint32] Vec3u* = TVec3[uint32] Vec4u* = TVec4[uint32] +converter ToVec1*[T: SomeNumber](orig: TVec3[T]|TVec4[T]): TVec1[T] = + TVec1[T]([orig[0]]) converter ToVec2*[T: SomeNumber](orig: TVec3[T]|TVec4[T]): TVec2[T] = TVec2[T]([orig[0], orig[1]]) converter ToVec3*[T: SomeNumber](orig: TVec4[T]): TVec3[T] = @@ -32,8 +38,11 @@ TVec4[T]([orig[0], orig[1], orig[2], value]) func ToVec3*[T: SomeNumber](orig: TVec2[T], value: T = default(T)): TVec3[T] = TVec3[T]([orig[0], orig[1], value]) +func ToVec2*[T: SomeNumber](orig: TVec1[T], value: T = default(T)): TVec2[T] = + TVec2[T]([orig[0], value]) # define some often used constants +func ConstOne1[T: SomeNumber](): auto {.compiletime.} = TVec1[T]([T(1)]) func ConstOne2[T: SomeNumber](): auto {.compiletime.} = TVec2[T]([T(1), T(1)]) func ConstOne3[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(1), T(1), T(1)]) func ConstOne4[T: SomeNumber](): auto {.compiletime.} = TVec4[T]([T(1), T(1), T(1), T(1)]) @@ -87,14 +96,17 @@ const X* = ConstX[float32]() const Y* = ConstY[float32]() const Z* = ConstZ[float32]() +const One1* = ConstOne1[float32]() const One2* = ConstOne2[float32]() const One3* = ConstOne3[float32]() const One4* = ConstOne4[float32]() +func NewVec1*[T](x: T): auto = TVec1([x]) func NewVec2*[T](x, y: T): auto = TVec2([x, y]) func NewVec3*[T](x, y, z: T): auto = TVec3([x, y, z]) func NewVec4*[T](x, y, z, w: T): auto = TVec4([x, y, z, w]) +func To*[T](v: TVec1): auto = TVec1([T(v[0])]) func To*[T](v: TVec2): auto = TVec2([T(v[0]), T(v[1])]) func To*[T](v: TVec3): auto = TVec3([T(v[0]), T(v[1]), T(v[2])]) func To*[T](v: TVec4): auto = TVec4([T(v[0]), T(v[1]), T(v[2]), T(v[3])]) @@ -105,10 +117,12 @@ items.add(&"{item.float:.5f}") & "(" & join(items, " ") & ")" +func `$`*(v: TVec1[SomeNumber]): string = toString[TVec1[SomeNumber]](v) func `$`*(v: TVec2[SomeNumber]): string = toString[TVec2[SomeNumber]](v) func `$`*(v: TVec3[SomeNumber]): string = toString[TVec3[SomeNumber]](v) func `$`*(v: TVec4[SomeNumber]): string = toString[TVec4[SomeNumber]](v) +func Length*(vec: TVec1): auto = vec[0] func Length*(vec: TVec2[SomeFloat]): auto = sqrt(vec[0] * vec[0] + vec[1] * vec[1]) func Length*(vec: TVec2[SomeInteger]): auto = sqrt(float(vec[0] * vec[0] + vec[1] * vec[1])) func Length*(vec: TVec3[SomeFloat]): auto = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]) @@ -119,6 +133,8 @@ func Normal*[T: SomeFloat](vec: TVec2[T]): auto = TVec2[T]([vec[1], -vec[0]]) +func Normalized*[T: SomeFloat](vec: TVec1[T]): auto = + return T(1) func Normalized*[T: SomeFloat](vec: TVec2[T]): auto = let l = vec.Length if l == 0: vec @@ -133,117 +149,124 @@ else: TVec4[T]([vec[0] / l, vec[1] / l, vec[2] / l, vec[3] / l]) # scalar operations +func `+`*(a: TVec1, b: SomeNumber): auto = TVec1([a[0] + b]) func `+`*(a: TVec2, b: SomeNumber): auto = TVec2([a[0] + b, a[1] + b]) func `+`*(a: TVec3, b: SomeNumber): auto = TVec3([a[0] + b, a[1] + b, a[2] + b]) -func `+`*(a: TVec4, b: SomeNumber): auto = TVec4([a[0] + b, a[1] + b, a[2] + b, - a[3] + b]) +func `+`*(a: TVec4, b: SomeNumber): auto = TVec4([a[0] + b, a[1] + b, a[2] + b, a[3] + b]) +func `-`*(a: TVec1, b: SomeNumber): auto = TVec1([a[0] - b]) func `-`*(a: TVec2, b: SomeNumber): auto = TVec2([a[0] - b, a[1] - b]) func `-`*(a: TVec3, b: SomeNumber): auto = TVec3([a[0] - b, a[1] - b, a[2] - b]) func `-`*(a: TVec4, b: SomeNumber): auto = TVec4([a[0] - b, a[1] - b, a[2] - b, a[3] - b]) +func `*`*(a: TVec1, b: SomeNumber): auto = TVec1([a[0] * b]) func `*`*(a: TVec2, b: SomeNumber): auto = TVec2([a[0] * b, a[1] * b]) func `*`*(a: TVec3, b: SomeNumber): auto = TVec3([a[0] * b, a[1] * b, a[2] * b]) func `*`*(a: TVec4, b: SomeNumber): auto = TVec4([a[0] * b, a[1] * b, a[2] * b, a[3] * b]) -func `/`*[T: SomeInteger](a: TVec2[T], b: SomeInteger): auto = TVec2([a[ - 0] div b, a[1] div b]) +func `/`*[T: SomeInteger](a: TVec1[T], b: SomeInteger): auto = TVec1([a[0] div b]) +func `/`*[T: SomeFloat](a: TVec1[T], b: SomeFloat): auto = TVec1([a[0] / b]) +func `/`*[T: SomeInteger](a: TVec2[T], b: SomeInteger): auto = TVec2([a[0] div b, a[1] div b]) func `/`*[T: SomeFloat](a: TVec2[T], b: SomeFloat): auto = TVec2([a[0] / b, a[1] / b]) -func `/`*[T: SomeInteger](a: TVec3[T], b: SomeInteger): auto = TVec3([a[ - 0] div b, a[1] div b, a[2] div b]) -func `/`*[T: SomeFloat](a: TVec3[T], b: SomeFloat): auto = TVec3([a[0] / b, a[ - 1] / b, a[2] / b]) -func `/`*[T: SomeInteger](a: TVec4[T], b: SomeInteger): auto = TVec4([a[ - 0] div b, a[1] div b, a[2] div b, a[3] div b]) -func `/`*[T: SomeFloat](a: TVec4[T], b: SomeFloat): auto = TVec4([a[0] / b, a[ - 1] / b, a[2] / b, a[3] / b]) +func `/`*[T: SomeInteger](a: TVec3[T], b: SomeInteger): auto = TVec3([a[0] div b, a[1] div b, a[2] div b]) +func `/`*[T: SomeFloat](a: TVec3[T], b: SomeFloat): auto = TVec3([a[0] / b, a[1] / b, a[2] / b]) +func `/`*[T: SomeInteger](a: TVec4[T], b: SomeInteger): auto = TVec4([a[0] div b, a[1] div b, a[2] div b, a[3] div b]) +func `/`*[T: SomeFloat](a: TVec4[T], b: SomeFloat): auto = TVec4([a[0] / b, a[1] / b, a[2] / b, a[3] / b]) +func `+`*(a: SomeNumber, b: TVec1): auto = TVec1([a + b[0]]) func `+`*(a: SomeNumber, b: TVec2): auto = TVec2([a + b[0], a + b[1]]) func `+`*(a: SomeNumber, b: TVec3): auto = TVec3([a + b[0], a + b[1], a + b[2]]) -func `+`*(a: SomeNumber, b: TVec4): auto = TVec4([a + b[0], a + b[1], a + b[2], - a + b[3]]) +func `+`*(a: SomeNumber, b: TVec4): auto = TVec4([a + b[0], a + b[1], a + b[2], a + b[3]]) +func `-`*(a: SomeNumber, b: TVec1): auto = TVec1([a - b[0]]) func `-`*(a: SomeNumber, b: TVec2): auto = TVec2([a - b[0], a - b[1]]) func `-`*(a: SomeNumber, b: TVec3): auto = TVec3([a - b[0], a - b[1], a - b[2]]) -func `-`*(a: SomeNumber, b: TVec4): auto = TVec4([a - b[0], a - b[1], a - b[2], - a - b[3]]) +func `-`*(a: SomeNumber, b: TVec4): auto = TVec4([a - b[0], a - b[1], a - b[2], a - b[3]]) +func `*`*(a: SomeNumber, b: TVec1): auto = TVec1([a * b[0]]) func `*`*(a: SomeNumber, b: TVec2): auto = TVec2([a * b[0], a * b[1]]) func `*`*(a: SomeNumber, b: TVec3): auto = TVec3([a * b[0], a * b[1], a * b[2]]) -func `*`*(a: SomeNumber, b: TVec4): auto = TVec4([a * b[0], a * b[1], a * b[2], - a * b[3]]) -func `/`*[T: SomeInteger](a: SomeInteger, b: TVec2[T]): auto = TVec2([a div b[ - 0], a div b[1]]) +func `*`*(a: SomeNumber, b: TVec4): auto = TVec4([a * b[0], a * b[1], a * b[2], a * b[3]]) +func `/`*[T: SomeInteger](a: SomeInteger, b: TVec1[T]): auto = TVec1([a div b[0]]) +func `/`*[T: SomeFloat](a: SomeFloat, b: TVec1[T]): auto = TVec1([a / b[0]]) +func `/`*[T: SomeInteger](a: SomeInteger, b: TVec2[T]): auto = TVec2([a div b[0], a div b[1]]) func `/`*[T: SomeFloat](a: SomeFloat, b: TVec2[T]): auto = TVec2([a / b[0], a / b[1]]) -func `/`*[T: SomeInteger](a: SomeInteger, b: TVec3[T]): auto = TVec3([a div b[ - 0], a div b[1], a div b[2]]) -func `/`*[T: SomeFloat](a: SomeFloat, b: TVec3[T]): auto = TVec3([a / b[0], a / - b[1], a / b[2]]) +func `/`*[T: SomeInteger](a: SomeInteger, b: TVec3[T]): auto = TVec3([a div b[0], a div b[1], a div b[2]]) +func `/`*[T: SomeFloat](a: SomeFloat, b: TVec3[T]): auto = TVec3([a / b[0], a / b[1], a / b[2]]) func `/`*[T: SomeInteger](a: SomeInteger, b: TVec4[T]): auto = TVec4([a div b[ 0], a div b[1], a div b[2], a div b[3]]) func `/`*[T: SomeFloat](a: SomeFloat, b: TVec4[T]): auto = TVec4([a / b[0], a / b[1], a / b[2], a / b[3]]) # compontent-wise operations +func `+`*(a, b: TVec1): auto = TVec1([a[0] + b[0]]) func `+`*(a, b: TVec2): auto = TVec2([a[0] + b[0], a[1] + b[1]]) func `+`*(a, b: TVec3): auto = TVec3([a[0] + b[0], a[1] + b[1], a[2] + b[2]]) -func `+`*(a, b: TVec4): auto = TVec4([a[0] + b[0], a[1] + b[1], a[2] + b[2], a[ - 3] + b[3]]) +func `+`*(a, b: TVec4): auto = TVec4([a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]]) +func `-`*(a: TVec1): auto = TVec1([-a[0]]) func `-`*(a: TVec2): auto = TVec2([-a[0], -a[1]]) func `-`*(a: TVec3): auto = TVec3([-a[0], -a[1], -a[2]]) func `-`*(a: TVec4): auto = TVec4([-a[0], -a[1], -a[2], -a[3]]) +func `-`*(a, b: TVec1): auto = TVec1([a[0] - b[0]]) func `-`*(a, b: TVec2): auto = TVec2([a[0] - b[0], a[1] - b[1]]) func `-`*(a, b: TVec3): auto = TVec3([a[0] - b[0], a[1] - b[1], a[2] - b[2]]) -func `-`*(a, b: TVec4): auto = TVec4([a[0] - b[0], a[1] - b[1], a[2] - b[2], a[ - 3] - b[3]]) +func `-`*(a, b: TVec4): auto = TVec4([a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]]) +func `*`*(a, b: TVec1): auto = TVec1([a[0] * b[0]]) func `*`*(a, b: TVec2): auto = TVec2([a[0] * b[0], a[1] * b[1]]) func `*`*(a, b: TVec3): auto = TVec3([a[0] * b[0], a[1] * b[1], a[2] * b[2]]) -func `*`*(a, b: TVec4): auto = TVec4([a[0] * b[0], a[1] * b[1], a[2] * b[2], a[ - 3] * b[3]]) -func `/`*[T: SomeInteger](a, b: TVec2[T]): auto = TVec2([a[0] div b[0], a[ - 1] div b[1]]) +func `*`*(a, b: TVec4): auto = TVec4([a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3]]) +func `/`*[T: SomeInteger](a, b: TVec1[T]): auto = TVec1([a[0] div b[0]]) +func `/`*[T: SomeFloat](a, b: TVec1[T]): auto = TVec1([a[0] / b[0]]) +func `/`*[T: SomeInteger](a, b: TVec2[T]): auto = TVec2([a[0] div b[0], a[1] div b[1]]) func `/`*[T: SomeFloat](a, b: TVec2[T]): auto = TVec2([a[0] / b[0], a[1] / b[1]]) -func `/`*[T: SomeInteger](a, b: TVec3[T]): auto = TVec3([a[0] div b[0], a[ - 1] div b[1], a[2] div b[2]]) -func `/`*[T: SomeFloat](a, b: TVec3[T]): auto = TVec3([a[0] / b[0], a[1] / b[1], - a[2] / b[2]]) -func `/`*[T: SomeInteger](a, b: TVec4[T]): auto = TVec4([a[0] div b[0], a[ - 1] div b[1], a[2] div b[2], a[3] div b[3]]) -func `/`*[T: SomeFloat](a, b: TVec4[T]): auto = TVec4([a[0] / b[0], a[1] / b[1], - a[2] / b[2], a[3] / b[3]]) +func `/`*[T: SomeInteger](a, b: TVec3[T]): auto = TVec3([a[0] div b[0], a[1] div b[1], a[2] div b[2]]) +func `/`*[T: SomeFloat](a, b: TVec3[T]): auto = TVec3([a[0] / b[0], a[1] / b[1], a[2] / b[2]]) +func `/`*[T: SomeInteger](a, b: TVec4[T]): auto = TVec4([a[0] div b[0], a[1] div b[1], a[2] div b[2], a[3] div b[3]]) +func `/`*[T: SomeFloat](a, b: TVec4[T]): auto = TVec4([a[0] / b[0], a[1] / b[1], a[2] / b[2], a[3] / b[3]]) # assignment operations, scalar +func `+=`*(a: var TVec1, b: SomeNumber) = a = a + b func `+=`*(a: var TVec2, b: SomeNumber) = a = a + b func `+=`*(a: var TVec3, b: SomeNumber) = a = a + b func `+=`*(a: var TVec4, b: SomeNumber) = a = a + b +func `-=`*(a: var TVec1, b: SomeNumber) = a = a - b func `-=`*(a: var TVec2, b: SomeNumber) = a = a - b func `-=`*(a: var TVec3, b: SomeNumber) = a = a - b func `-=`*(a: var TVec4, b: SomeNumber) = a = a - b +func `*=`*(a: var TVec1, b: SomeNumber) = a = a * b func `*=`*(a: var TVec2, b: SomeNumber) = a = a * b func `*=`*(a: var TVec3, b: SomeNumber) = a = a * b func `*=`*(a: var TVec4, b: SomeNumber) = a = a * b +func `/=`*(a: var TVec1, b: SomeNumber) = a = a / b func `/=`*(a: var TVec2, b: SomeNumber) = a = a / b func `/=`*(a: var TVec3, b: SomeNumber) = a = a / b func `/=`*(a: var TVec4, b: SomeNumber) = a = a / b # assignment operations, vector +func `+=`*(a: var TVec1, b: TVec1) = a = a + b func `+=`*(a: var TVec2, b: TVec2) = a = a + b func `+=`*(a: var TVec3, b: TVec3) = a = a + b func `+=`*(a: var TVec4, b: TVec4) = a = a + b +func `-=`*(a: var TVec1, b: TVec1) = a = a - b func `-=`*(a: var TVec2, b: TVec2) = a = a - b func `-=`*(a: var TVec3, b: TVec3) = a = a - b func `-=`*(a: var TVec4, b: TVec4) = a = a - b +func `*=`*(a: var TVec1, b: TVec1) = a = a * b func `*=`*(a: var TVec2, b: TVec2) = a = a * b func `*=`*(a: var TVec3, b: TVec3) = a = a * b func `*=`*(a: var TVec4, b: TVec4) = a = a * b +func `/=`*(a: var TVec1, b: TVec1) = a = a / b func `/=`*(a: var TVec2, b: TVec2) = a = a / b func `/=`*(a: var TVec3, b: TVec3) = a = a / b func `/=`*(a: var TVec4, b: TVec4) = a = a / b # special operations +func Pow*(a: TVec1, b: SomeNumber): auto = + TVec1([pow(a[0], b)]) func Pow*(a: TVec2, b: SomeNumber): auto = TVec2([pow(a[0], b), pow(a[1], b)]) func Pow*(a: TVec3, b: SomeNumber): auto = TVec3([pow(a[0], b), pow(a[1], b), pow(a[2], b)]) func Pow*(a: TVec4, b: SomeNumber): auto = TVec4([pow(a[0], b), pow(a[1], b), pow(a[2], b), pow(a[3], b)]) +func Dot*(a, b: TVec1): auto = a[0] * b[0] func Dot*(a, b: TVec2): auto = a[0] * b[0] + a[1] * b[1] func Dot*(a, b: TVec3): auto = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] func Dot*(a, b: TVec4): auto = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3] @@ -342,6 +365,7 @@ for i in 0 ..< result.len: result[i] = rand(1.0) +makeRandomInit(TVec1) makeRandomInit(TVec2) makeRandomInit(TVec3) makeRandomInit(TVec4) diff -r 3f43c7163029 -r 565fcfde427a static_utils.nim --- a/static_utils.nim Sat Jul 06 00:31:17 2024 +0700 +++ b/static_utils.nim Sat Jul 06 15:05:28 2024 +0700 @@ -44,18 +44,16 @@ DirectGPUMemory = object vk: VkDeviceMemory size: uint64 - data: pointer - needsFlush: bool # usually true + rawPointer: pointer GPUMemory = IndirectGPUMemory | DirectGPUMemory Buffer[TMemory: GPUMemory] = object - memory: TMemory vk: VkBuffer - offset: uint64 size: uint64 + rawPointer: pointer Texture[T: TextureType, TMemory: GPUMemory] = object + vk: VkImage memory: TMemory - vk: VkImage format: VkFormat imageview: VkImageView sampler: VkSampler @@ -102,6 +100,10 @@ func depth(texture: Texture): int = default(elementType(texture.data)).len +func pointerOffset[T: SomeInteger](p: pointer, offset: T): pointer = + cast[pointer](cast[T](p) + offset) + + proc GetVkFormat(depth: int, usage: openArray[VkImageUsageFlagBits]): VkFormat = const DEPTH_FORMAT_MAP = [ 0: [VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED], @@ -330,9 +332,9 @@ template size(gpuValue: GPUValue): uint64 = sizeof(gpuValue.data).uint64 -template datapointer(gpuArray: GPUArray): pointer = +template rawPointer(gpuArray: GPUArray): pointer = addr(gpuArray.data[0]) -template datapointer(gpuValue: GPUValue): pointer = +template rawPointer(gpuValue: GPUValue): pointer = addr(gpuValue.data) proc RequiredMemorySize(buffer: VkBuffer): uint64 = @@ -370,7 +372,7 @@ assert score > 0, "Unable to find integrated or discrete GPU" -proc GetDirectMemoryTypeIndex(): uint32 = +proc GetDirectMemoryType(): uint32 = var physicalProperties: VkPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr(physicalProperties)) @@ -396,72 +398,18 @@ return i assert false, &"Queue of type {qType} not found" -proc GetQueue(device: VkDevice, queueFamilyIndex: uint32, qType: VkQueueFlagBits): VkQueue = - vkGetDeviceQueue( - device, - queueFamilyIndex, - 0, - addr(result), - ) - proc GetSurfaceFormat(): VkFormat = # EVERY windows driver and almost every linux driver should support this VK_FORMAT_B8G8R8A8_SRGB -template WithSingleUseCommandBuffer(cmd, body: untyped): untyped = - block: - var - commandBufferPool: VkCommandPool - createInfo = VkCommandPoolCreateInfo( - sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT], - queueFamilyIndex: vulkan.queueFamilyIndex, - ) - checkVkResult vkCreateCommandPool(vulkan.device, addr createInfo, nil, addr(commandBufferPool)) - var - `cmd` {.inject.}: VkCommandBuffer - allocInfo = VkCommandBufferAllocateInfo( - sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - commandPool: commandBufferPool, - level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, - commandBufferCount: 1, - ) - checkVkResult vulkan.device.vkAllocateCommandBuffers(addr allocInfo, addr(`cmd`)) - var beginInfo = VkCommandBufferBeginInfo( - sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), - ) - checkVkResult `cmd`.vkBeginCommandBuffer(addr beginInfo) - - body - - checkVkResult `cmd`.vkEndCommandBuffer() - var submitInfo = VkSubmitInfo( - sType: VK_STRUCTURE_TYPE_SUBMIT_INFO, - commandBufferCount: 1, - pCommandBuffers: addr(`cmd`), - ) - - var - fence: VkFence - fenceInfo = VkFenceCreateInfo( - sType: VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - # flags: toBits [VK_FENCE_CREATE_SIGNALED_BIT] - ) - checkVkResult vulkan.device.vkCreateFence(addr(fenceInfo), nil, addr(fence)) - checkVkResult vkQueueSubmit(vulkan.queue, 1, addr(submitInfo), fence) - checkVkResult vkWaitForFences(vulkan.device, 1, addr fence, false, high(uint64)) - vkDestroyCommandPool(vulkan.device, commandBufferPool, nil) - - proc UpdateGPUBuffer(gpuData: GPUData) = if gpuData.size == 0: return when UsesDirectMemory(gpuData): - copyMem(cast[pointer](cast[uint64](gpuData.buffer.memory.data) + gpuData.buffer.offset + gpuData.offset), gpuData.datapointer, gpuData.size) + copyMem(pointerOffset(gpuData.buffer.rawPointer, gpuData.offset), gpuData.rawPointer, gpuData.size) else: - WithStagingBuffer(gpuData.buffer.vk, gpuData.buffer.vk.RequiredMemorySize(), GetDirectMemoryTypeIndex(), stagingPtr): - copyMem(stagingPtr, gpuData.datapointer, gpuData.size) + WithStagingBuffer((gpuData.buffer.vk, gpuData.offset), gpuData.buffer.vk.RequiredMemorySize(), GetDirectMemoryType(), stagingPtr): + copyMem(stagingPtr, gpuData.rawPointer, gpuData.size) proc UpdateAllGPUBuffers[T](value: T) = for name, fieldvalue in value.fieldPairs(): @@ -481,6 +429,7 @@ # when typeof(value) is Texture: # assert value.texture.vk.Valid + # TODO: missing stuff here? only for FiF, but not multiple different sets? # allocate var layouts = newSeqWith(descriptorSet.vk.len, layout) var allocInfo = VkDescriptorSetAllocateInfo( @@ -491,7 +440,8 @@ ) checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer) - # write + # allocate seq with high cap to prevent realocation while adding to set + # (which invalidates pointers that are passed to the vulkan api call) var descriptorSetWrites = newSeqOfCap[VkWriteDescriptorSet](1024) var imageWrites = newSeqOfCap[VkDescriptorImageInfo](1024) var bufferWrites = newSeqOfCap[VkDescriptorBufferInfo](1024) @@ -501,8 +451,8 @@ when typeof(fieldValue) is GPUValue: bufferWrites.add VkDescriptorBufferInfo( buffer: fieldValue.buffer.vk, - offset: fieldValue.buffer.offset, - range: fieldValue.buffer.size, + offset: fieldValue.offset, + range: fieldValue.size, ) descriptorSetWrites.add VkWriteDescriptorSet( sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, @@ -533,7 +483,6 @@ elif typeof(fieldValue) is array: discard when elementType(fieldValue) is Texture: - echo "Add texture array descriptor set write for set " & $i & " " & fieldName for textureIndex in 0 ..< descriptorCount: imageWrites.add VkDescriptorImageInfo( sampler: fieldValue[textureIndex].sampler, @@ -547,7 +496,7 @@ dstArrayElement: 0, descriptorType: descriptorType, descriptorCount: descriptorCount, - pImageInfo: addr(imageWrites[^fieldValue.len]), + pImageInfo: addr(imageWrites[^descriptorCount.int]), pBufferInfo: nil, ) else: @@ -555,7 +504,13 @@ else: {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).} - vkUpdateDescriptorSets(vulkan.device, descriptorSetWrites.len.uint32, descriptorSetWrites.ToCPointer, 0, nil) + vkUpdateDescriptorSets( + device = vulkan.device, + descriptorWriteCount = descriptorSetWrites.len.uint32, + pDescriptorWrites = descriptorSetWrites.ToCPointer, + descriptorCopyCount = 0, + pDescriptorCopies = nil, + ) converter toVkIndexType(indexType: IndexType): VkIndexType = case indexType: @@ -974,7 +929,6 @@ proc AllocateDirectMemory(size: uint64): DirectGPUMemory = result.size = size - result.needsFlush = true # find a good memory type var physicalProperties: VkPhysicalDeviceMemoryProperties @@ -990,23 +944,22 @@ if size > biggestHeap: biggestHeap = size memoryTypeIndex = i - result.needsFlush = not (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in flags) assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" - result.vk = svkAllocateMemory(result.size, GetDirectMemoryTypeIndex()) + result.vk = svkAllocateMemory(result.size, GetDirectMemoryType()) checkVkResult vkMapMemory( device = vulkan.device, memory = result.vk, offset = 0'u64, size = result.size, flags = VkMemoryMapFlags(0), - ppData = addr(result.data) + ppData = addr(result.rawPointer) ) proc AllocateIndirectBuffer(renderData: var RenderData, size: uint64, btype: BufferType) = if size == 0: return - var buffer = Buffer[IndirectGPUMemory](size: size) + var buffer = Buffer[IndirectGPUMemory](size: size, rawPointer: nil) let usageFlags = case btype: of VertexBuffer: [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] @@ -1018,10 +971,9 @@ # TODO: use RequiredMemorySize() for (memory, usedOffset) in renderData.indirectMemory.mitems: if memory.size - usedOffset >= size: - buffer.offset = usedOffset # create buffer buffer.vk = svkCreateBuffer(buffer.size, usageFlags) - checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset) + checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, usedOffset) renderData.indirectBuffers.add (buffer, btype, 0'u64) # update memory area offset usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT) @@ -1045,9 +997,9 @@ # TODO: use RequiredMemorySize() for (memory, usedOffset) in renderData.directMemory.mitems: if memory.size - usedOffset >= size: - buffer.offset = usedOffset buffer.vk = svkCreateBuffer(buffer.size, usageFlags) - checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset) + checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, usedOffset) + buffer.rawPointer = pointerOffset(memory.rawPointer, usedOffset) renderData.directBuffers.add (buffer, btype, 0'u64) # update memory area offset usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT) @@ -1289,7 +1241,7 @@ # data transfer and layout transition TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - WithStagingBuffer((texture.vk, texture.imageview, texture.width, texture.height), size, GetDirectMemoryTypeIndex(), stagingPtr): + WithStagingBuffer((texture.vk, texture.imageview, texture.width, texture.height), size, GetDirectMemoryType(), stagingPtr): copyMem(stagingPtr, texture.data.ToCPointer, size) TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) @@ -1299,7 +1251,13 @@ proc UploadTextures(renderdata: var RenderData, descriptorSet: var DescriptorSet) = for name, value in fieldPairs(descriptorSet.data): when typeof(value) is Texture: + echo "Upload texture '", name, "'" renderdata.createTextureImage(value) + elif typeof(value) is array: + when elementType(value) is Texture: + echo "Upload texture ARRAY '", name, "'" + for texture in value.mitems: + renderdata.createTextureImage(texture) proc HasGPUValueField[T](name: static string): bool {.compileTime.} = for fieldname, value in default(T).fieldPairs(): @@ -1480,7 +1438,7 @@ device: dev, physicalDevice: pDevice, queueFamilyIndex: qfi, - queue: dev.GetQueue(qfi, VK_QUEUE_GRAPHICS_BIT) + queue: svkGetDeviceQueue(dev, qfi, VK_QUEUE_GRAPHICS_BIT) ) var myMesh1 = MeshA( @@ -1488,15 +1446,16 @@ ) var uniforms1 = DescriptorSet[UniformsA, MaterialSet]( data: UniformsA( + defaultTexture: Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), materials: GPUValue[array[3, MaterialA], IndirectGPUMemory](data: [ MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)), MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)), MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)), ]), materialTextures: [ - Texture[TVec3[uint8], IndirectGPUMemory](), - Texture[TVec3[uint8], IndirectGPUMemory](), - Texture[TVec3[uint8], IndirectGPUMemory](), + Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), + Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), + Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), ] ) ) @@ -1504,7 +1463,12 @@ rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]), objPosition: GPUArray[Vec3f, IndirectGPUMemory](data: @[NewVec3f(0, 0, 0), NewVec3f(1, 1, 1)]), ) - var myGlobals = DescriptorSet[GlobalsA, GlobalSet]() + var myGlobals = DescriptorSet[GlobalsA, GlobalSet]( + data: GlobalsA( + fontAtlas: Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), + settings: GPUValue[ShaderSettings, IndirectGPUMemory](data: ShaderSettings(gamma: 1.0)) + ) + ) # setup for rendering (TODO: swapchain & framebuffers) let renderpass = CreateRenderPass(GetSurfaceFormat()) @@ -1567,11 +1531,8 @@ renderdata.AssignIndirectBuffers(UniformBuffer, myGlobals) renderdata.AssignDirectBuffers(UniformBuffer, myGlobals) + renderdata.UploadTextures(myGlobals) renderdata.UploadTextures(uniforms1) - renderdata.UploadTextures(myGlobals) - - echo uniforms1.data.materialTextures - # copy everything to GPU echo "Copying all data to GPU memory"