comparison static_utils.nim @ 1184:3f43c7163029 compiletime-tests

sync from bedroom to office
author sam <sam@basx.dev>
date Sat, 06 Jul 2024 00:31:17 +0700
parents 850450bfe2a2
children 565fcfde427a
comparison
equal deleted inserted replaced
1183:850450bfe2a2 1184:3f43c7163029
10 import semicongine/core/utils 10 import semicongine/core/utils
11 import semicongine/core/vector 11 import semicongine/core/vector
12 import semicongine/core/matrix 12 import semicongine/core/matrix
13 import semicongine/core/vulkanapi 13 import semicongine/core/vulkanapi
14 14
15 import ./vulkan_utils
16
15 template VertexAttribute {.pragma.} 17 template VertexAttribute {.pragma.}
16 template InstanceAttribute {.pragma.} 18 template InstanceAttribute {.pragma.}
17 template Pass {.pragma.} 19 template Pass {.pragma.}
18 template PassFlat {.pragma.} 20 template PassFlat {.pragma.}
19 template ShaderOutput {.pragma.} 21 template ShaderOutput {.pragma.}
24 const BUFFER_ALIGNMENT = 64'u64 # align offsets inside buffers along this alignment 26 const BUFFER_ALIGNMENT = 64'u64 # align offsets inside buffers along this alignment
25 27
26 # some globals that will (likely?) never change during the life time of the engine 28 # some globals that will (likely?) never change during the life time of the engine
27 type 29 type
28 SupportedGPUType = float32 | float64 | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | TVec2[int32] | TVec2[int64] | TVec3[int32] | TVec3[int64] | TVec4[int32] | TVec4[int64] | TVec2[uint32] | TVec2[uint64] | TVec3[uint32] | TVec3[uint64] | TVec4[uint32] | TVec4[uint64] | TVec2[float32] | TVec2[float64] | TVec3[float32] | TVec3[float64] | TVec4[float32] | TVec4[float64] | TMat2[float32] | TMat2[float64] | TMat23[float32] | TMat23[float64] | TMat32[float32] | TMat32[float64] | TMat3[float32] | TMat3[float64] | TMat34[float32] | TMat34[float64] | TMat43[float32] | TMat43[float64] | TMat4[float32] | TMat4[float64] 30 SupportedGPUType = float32 | float64 | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | TVec2[int32] | TVec2[int64] | TVec3[int32] | TVec3[int64] | TVec4[int32] | TVec4[int64] | TVec2[uint32] | TVec2[uint64] | TVec3[uint32] | TVec3[uint64] | TVec4[uint32] | TVec4[uint64] | TVec2[float32] | TVec2[float64] | TVec3[float32] | TVec3[float64] | TVec4[float32] | TVec4[float64] | TMat2[float32] | TMat2[float64] | TMat23[float32] | TMat23[float64] | TMat32[float32] | TMat32[float64] | TMat3[float32] | TMat3[float64] | TMat34[float32] | TMat34[float64] | TMat43[float32] | TMat43[float64] | TMat4[float32] | TMat4[float64]
31 TextureType = TVec1[uint8] | TVec2[uint8] | TVec3[uint8] | TVec4[uint8]
29 32
30 ShaderObject[TShader] = object 33 ShaderObject[TShader] = object
31 vertexShader: VkShaderModule 34 vertexShader: VkShaderModule
32 fragmentShader: VkShaderModule 35 fragmentShader: VkShaderModule
33
34 VulkanGlobals = object
35 instance: VkInstance
36 device: VkDevice
37 physicalDevice: VkPhysicalDevice
38 queueFamilyIndex: uint32
39 queue: VkQueue
40 36
41 IndexType = enum 37 IndexType = enum
42 None, UInt8, UInt16, UInt32 38 None, UInt8, UInt16, UInt32
43 39
44 IndirectGPUMemory = object 40 IndirectGPUMemory = object
55 Buffer[TMemory: GPUMemory] = object 51 Buffer[TMemory: GPUMemory] = object
56 memory: TMemory 52 memory: TMemory
57 vk: VkBuffer 53 vk: VkBuffer
58 offset: uint64 54 offset: uint64
59 size: uint64 55 size: uint64
60 Texture[Channels: static int, TMemory: GPUMemory] = object 56 Texture[T: TextureType, TMemory: GPUMemory] = object
61 memory: TMemory 57 memory: TMemory
62 vk: VkImage 58 vk: VkImage
59 format: VkFormat
63 imageview: VkImageView 60 imageview: VkImageView
64 sampler: VkSampler 61 sampler: VkSampler
65 offset: uint64 62 offset: uint64
66 size: uint64 63 size: uint64
67 width: int 64 width: uint32
68 data: seq[array[Channels, uint8]] 65 height: uint32
66 data: seq[T]
69 67
70 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object 68 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object
71 data: seq[T] 69 data: seq[T]
72 buffer: Buffer[TMemory] 70 buffer: Buffer[TMemory]
73 offset: uint64 71 offset: uint64
96 indirectMemory: seq[tuple[memory: IndirectGPUMemory, usedOffset: uint64]] 94 indirectMemory: seq[tuple[memory: IndirectGPUMemory, usedOffset: uint64]]
97 directMemory: seq[tuple[memory: DirectGPUMemory, usedOffset: uint64]] 95 directMemory: seq[tuple[memory: DirectGPUMemory, usedOffset: uint64]]
98 indirectBuffers: seq[tuple[buffer: Buffer[IndirectGPUMemory], btype: BufferType, usedOffset: uint64]] 96 indirectBuffers: seq[tuple[buffer: Buffer[IndirectGPUMemory], btype: BufferType, usedOffset: uint64]]
99 directBuffers: seq[tuple[buffer: Buffer[DirectGPUMemory], btype: BufferType, usedOffset: uint64]] 97 directBuffers: seq[tuple[buffer: Buffer[DirectGPUMemory], btype: BufferType, usedOffset: uint64]]
100 98
101 var vulkan: VulkanGlobals 99 func size(texture: Texture): uint64 =
100 texture.data.len * sizeof(elementType(texture.data))
101
102 func depth(texture: Texture): int =
103 default(elementType(texture.data)).len
104
105 proc GetVkFormat(depth: int, usage: openArray[VkImageUsageFlagBits]): VkFormat =
106 const DEPTH_FORMAT_MAP = [
107 0: [VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED],
108 1: [VK_FORMAT_R8_SRGB, VK_FORMAT_R8_UNORM],
109 2: [VK_FORMAT_R8G8_SRGB, VK_FORMAT_R8G8_UNORM],
110 3: [VK_FORMAT_R8G8B8_SRGB, VK_FORMAT_R8G8B8_UNORM],
111 4: [VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_R8G8B8A8_UNORM],
112 ]
113
114 var formatProperties = VkImageFormatProperties2(sType: VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2)
115 for format in DEPTH_FORMAT_MAP[depth]:
116 var formatInfo = VkPhysicalDeviceImageFormatInfo2(
117 sType: VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
118 format: format,
119 thetype: VK_IMAGE_TYPE_2D,
120 tiling: VK_IMAGE_TILING_OPTIMAL,
121 usage: usage.toBits,
122 )
123 let formatCheck = vkGetPhysicalDeviceImageFormatProperties2(
124 vulkan.physicalDevice,
125 addr formatInfo,
126 addr formatProperties,
127 )
128 if formatCheck == VK_SUCCESS: # found suitable format
129 return format
130 elif formatCheck == VK_ERROR_FORMAT_NOT_SUPPORTED: # nope, try to find other format
131 continue
132 else: # raise error
133 checkVkResult formatCheck
134
135 assert false, "Unable to find format for textures"
136
102 137
103 func alignedTo[T: SomeInteger](value: T, alignment: T): T = 138 func alignedTo[T: SomeInteger](value: T, alignment: T): T =
104 let remainder = value mod alignment 139 let remainder = value mod alignment
105 if remainder == 0: 140 if remainder == 0:
106 return value 141 return value
298 template datapointer(gpuArray: GPUArray): pointer = 333 template datapointer(gpuArray: GPUArray): pointer =
299 addr(gpuArray.data[0]) 334 addr(gpuArray.data[0])
300 template datapointer(gpuValue: GPUValue): pointer = 335 template datapointer(gpuValue: GPUValue): pointer =
301 addr(gpuValue.data) 336 addr(gpuValue.data)
302 337
303 proc AllocationSize(buffer: Buffer): uint64 = 338 proc RequiredMemorySize(buffer: VkBuffer): uint64 =
304 var req: VkMemoryRequirements 339 var req: VkMemoryRequirements
305 vkGetBufferMemoryRequirements(vulkan.device, buffer.vk, addr(req)) 340 vkGetBufferMemoryRequirements(vulkan.device, buffer, addr(req))
341 return req.size
342
343 proc RequiredMemorySize(image: VkImage): uint64 =
344 var req: VkMemoryRequirements
345 vkGetImageMemoryRequirements(vulkan.device, image, addr req)
306 return req.size 346 return req.size
307 347
308 proc GetPhysicalDevice(instance: VkInstance): VkPhysicalDevice = 348 proc GetPhysicalDevice(instance: VkInstance): VkPhysicalDevice =
309 var nDevices: uint32 349 var nDevices: uint32
310 checkVkResult vkEnumeratePhysicalDevices(instance, addr(nDevices), nil) 350 checkVkResult vkEnumeratePhysicalDevices(instance, addr(nDevices), nil)
366 406
367 proc GetSurfaceFormat(): VkFormat = 407 proc GetSurfaceFormat(): VkFormat =
368 # EVERY windows driver and almost every linux driver should support this 408 # EVERY windows driver and almost every linux driver should support this
369 VK_FORMAT_B8G8R8A8_SRGB 409 VK_FORMAT_B8G8R8A8_SRGB
370 410
371 template WithSingleUseCommandBuffer(device: VkDevice, cmd, body: untyped): untyped = 411 template WithSingleUseCommandBuffer(cmd, body: untyped): untyped =
372 block: 412 block:
373 var 413 var
374 commandBufferPool: VkCommandPool 414 commandBufferPool: VkCommandPool
375 createInfo = VkCommandPoolCreateInfo( 415 createInfo = VkCommandPoolCreateInfo(
376 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 416 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
377 flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT], 417 flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
378 queueFamilyIndex: vulkan.queueFamilyIndex, 418 queueFamilyIndex: vulkan.queueFamilyIndex,
379 ) 419 )
380 checkVkResult vkCreateCommandPool(device, addr createInfo, nil, addr(commandBufferPool)) 420 checkVkResult vkCreateCommandPool(vulkan.device, addr createInfo, nil, addr(commandBufferPool))
381 var 421 var
382 `cmd` {.inject.}: VkCommandBuffer 422 `cmd` {.inject.}: VkCommandBuffer
383 allocInfo = VkCommandBufferAllocateInfo( 423 allocInfo = VkCommandBufferAllocateInfo(
384 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 424 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
385 commandPool: commandBufferPool, 425 commandPool: commandBufferPool,
386 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, 426 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
387 commandBufferCount: 1, 427 commandBufferCount: 1,
388 ) 428 )
389 checkVkResult device.vkAllocateCommandBuffers(addr allocInfo, addr(`cmd`)) 429 checkVkResult vulkan.device.vkAllocateCommandBuffers(addr allocInfo, addr(`cmd`))
390 var beginInfo = VkCommandBufferBeginInfo( 430 var beginInfo = VkCommandBufferBeginInfo(
391 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 431 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
392 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), 432 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
393 ) 433 )
394 checkVkResult `cmd`.vkBeginCommandBuffer(addr beginInfo) 434 checkVkResult `cmd`.vkBeginCommandBuffer(addr beginInfo)
406 fence: VkFence 446 fence: VkFence
407 fenceInfo = VkFenceCreateInfo( 447 fenceInfo = VkFenceCreateInfo(
408 sType: VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 448 sType: VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
409 # flags: toBits [VK_FENCE_CREATE_SIGNALED_BIT] 449 # flags: toBits [VK_FENCE_CREATE_SIGNALED_BIT]
410 ) 450 )
411 checkVkResult device.vkCreateFence(addr(fenceInfo), nil, addr(fence)) 451 checkVkResult vulkan.device.vkCreateFence(addr(fenceInfo), nil, addr(fence))
412 checkVkResult vkQueueSubmit(vulkan.queue, 1, addr(submitInfo), fence) 452 checkVkResult vkQueueSubmit(vulkan.queue, 1, addr(submitInfo), fence)
413 checkVkResult vkWaitForFences(device, 1, addr fence, false, high(uint64)) 453 checkVkResult vkWaitForFences(vulkan.device, 1, addr fence, false, high(uint64))
414 vkDestroyCommandPool(device, commandBufferPool, nil) 454 vkDestroyCommandPool(vulkan.device, commandBufferPool, nil)
415 455
416 456
417 proc UpdateGPUBuffer(gpuData: GPUData) = 457 proc UpdateGPUBuffer(gpuData: GPUData) =
418 if gpuData.size == 0: 458 if gpuData.size == 0:
419 return 459 return
420 when UsesDirectMemory(gpuData): 460 when UsesDirectMemory(gpuData):
421 copyMem(cast[pointer](cast[uint64](gpuData.buffer.memory.data) + gpuData.buffer.offset + gpuData.offset), gpuData.datapointer, gpuData.size) 461 copyMem(cast[pointer](cast[uint64](gpuData.buffer.memory.data) + gpuData.buffer.offset + gpuData.offset), gpuData.datapointer, gpuData.size)
422 else: 462 else:
423 var 463 WithStagingBuffer(gpuData.buffer.vk, gpuData.buffer.vk.RequiredMemorySize(), GetDirectMemoryTypeIndex(), stagingPtr):
424 stagingBuffer: VkBuffer 464 copyMem(stagingPtr, gpuData.datapointer, gpuData.size)
425 createInfo = VkBufferCreateInfo(
426 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
427 flags: VkBufferCreateFlags(0),
428 size: gpuData.size,
429 usage: toBits([VK_BUFFER_USAGE_TRANSFER_SRC_BIT]),
430 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
431 )
432 checkVkResult vkCreateBuffer(
433 device = vulkan.device,
434 pCreateInfo = addr(createInfo),
435 pAllocator = nil,
436 pBuffer = addr(stagingBuffer),
437 )
438 var
439 stagingMemory: VkDeviceMemory
440 stagingPtr: pointer
441 memoryAllocationInfo = VkMemoryAllocateInfo(
442 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
443 allocationSize: gpuData.buffer.AllocationSize(),
444 memoryTypeIndex: GetDirectMemoryTypeIndex(),
445 )
446 checkVkResult vkAllocateMemory(
447 vulkan.device,
448 addr(memoryAllocationInfo),
449 nil,
450 addr(stagingMemory),
451 )
452 checkVkResult vkBindBufferMemory(vulkan.device, stagingBuffer, stagingMemory, 0)
453 checkVkResult vkMapMemory(
454 device = vulkan.device,
455 memory = stagingMemory,
456 offset = 0'u64,
457 size = VK_WHOLE_SIZE,
458 flags = VkMemoryMapFlags(0),
459 ppData = addr(stagingPtr)
460 )
461 copyMem(stagingPtr, gpuData.datapointer, gpuData.size)
462 var stagingRange = VkMappedMemoryRange(
463 sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
464 memory: stagingMemory,
465 size: VK_WHOLE_SIZE,
466 )
467 checkVkResult vkFlushMappedMemoryRanges(vulkan.device, 1, addr(stagingRange))
468
469 WithSingleUseCommandBuffer(vulkan.device, commandBuffer):
470 var copyRegion = VkBufferCopy(size: gpuData.size)
471 vkCmdCopyBuffer(commandBuffer, stagingBuffer, gpuData.buffer.vk, 1, addr(copyRegion))
472
473 vkDestroyBuffer(vulkan.device, stagingBuffer, nil)
474 vkFreeMemory(vulkan.device, stagingMemory, nil)
475 465
476 proc UpdateAllGPUBuffers[T](value: T) = 466 proc UpdateAllGPUBuffers[T](value: T) =
477 for name, fieldvalue in value.fieldPairs(): 467 for name, fieldvalue in value.fieldPairs():
478 when typeof(fieldvalue) is GPUData: 468 when typeof(fieldvalue) is GPUData:
479 UpdateGPUBuffer(fieldvalue) 469 UpdateGPUBuffer(fieldvalue)
500 pSetLayouts: layouts.ToCPointer, 490 pSetLayouts: layouts.ToCPointer,
501 ) 491 )
502 checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer) 492 checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer)
503 493
504 # write 494 # write
505 var descriptorSetWrites = newSeq[VkWriteDescriptorSet](descriptorSet.vk.len) 495 var descriptorSetWrites = newSeqOfCap[VkWriteDescriptorSet](1024)
506 496 var imageWrites = newSeqOfCap[VkDescriptorImageInfo](1024)
507 var descriptorBinding = 0 497 var bufferWrites = newSeqOfCap[VkDescriptorBufferInfo](1024)
498
508 ForDescriptorFields(descriptorSet.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber): 499 ForDescriptorFields(descriptorSet.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber):
509 for i in 0 ..< descriptorSet.vk.len: 500 for i in 0 ..< descriptorSet.vk.len:
510 when typeof(fieldValue) is GPUValue: 501 when typeof(fieldValue) is GPUValue:
511 let bufferInfo = VkDescriptorBufferInfo( 502 bufferWrites.add VkDescriptorBufferInfo(
512 buffer: fieldValue.buffer.vk, 503 buffer: fieldValue.buffer.vk,
513 offset: fieldValue.buffer.offset, 504 offset: fieldValue.buffer.offset,
514 range: fieldValue.buffer.size, 505 range: fieldValue.buffer.size,
515 ) 506 )
516 descriptorSetWrites[i] = VkWriteDescriptorSet( 507 descriptorSetWrites.add VkWriteDescriptorSet(
517 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 508 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
518 dstSet: descriptorSet.vk[i], 509 dstSet: descriptorSet.vk[i],
519 dstBinding: descriptorBindingNumber, 510 dstBinding: descriptorBindingNumber,
520 dstArrayElement: uint32(0), 511 dstArrayElement: 0,
521 descriptorType: descriptorType, 512 descriptorType: descriptorType,
522 descriptorCount: descriptorCount, 513 descriptorCount: descriptorCount,
523 pImageInfo: nil, 514 pImageInfo: nil,
524 pBufferInfo: addr(bufferInfo), 515 pBufferInfo: addr(bufferWrites[^1]),
525 ) 516 )
526 elif typeof(fieldValue) is Texture: 517 elif typeof(fieldValue) is Texture:
527 let imageInfo = VkDescriptorImageInfo( 518 imageWrites.add VkDescriptorImageInfo(
528 sampler: fieldValue.sampler, 519 sampler: fieldValue.sampler,
529 imageView: fieldValue.imageView, 520 imageView: fieldValue.imageView,
530 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 521 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
531 ) 522 )
532 descriptorSetWrites[i] = VkWriteDescriptorSet( 523 descriptorSetWrites.add VkWriteDescriptorSet(
533 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 524 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
534 dstSet: descriptorSet.vk[i], 525 dstSet: descriptorSet.vk[i],
535 dstBinding: descriptorBindingNumber, 526 dstBinding: descriptorBindingNumber,
536 dstArrayElement: uint32(0), 527 dstArrayElement: 0,
537 descriptorType: descriptorType, 528 descriptorType: descriptorType,
538 descriptorCount: descriptorCount, 529 descriptorCount: descriptorCount,
539 pImageInfo: addr(imageInfo), 530 pImageInfo: addr(imageWrites[^1]),
540 pBufferInfo: nil, 531 pBufferInfo: nil,
541 ) 532 )
533 elif typeof(fieldValue) is array:
534 discard
535 when elementType(fieldValue) is Texture:
536 echo "Add texture array descriptor set write for set " & $i & " " & fieldName
537 for textureIndex in 0 ..< descriptorCount:
538 imageWrites.add VkDescriptorImageInfo(
539 sampler: fieldValue[textureIndex].sampler,
540 imageView: fieldValue[textureIndex].imageView,
541 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
542 )
543 descriptorSetWrites.add VkWriteDescriptorSet(
544 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
545 dstSet: descriptorSet.vk[i],
546 dstBinding: descriptorBindingNumber,
547 dstArrayElement: 0,
548 descriptorType: descriptorType,
549 descriptorCount: descriptorCount,
550 pImageInfo: addr(imageWrites[^fieldValue.len]),
551 pBufferInfo: nil,
552 )
553 else:
554 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).}
542 else: 555 else:
543 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).} 556 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).}
544 557
545
546 vkUpdateDescriptorSets(vulkan.device, descriptorSetWrites.len.uint32, descriptorSetWrites.ToCPointer, 0, nil) 558 vkUpdateDescriptorSets(vulkan.device, descriptorSetWrites.len.uint32, descriptorSetWrites.ToCPointer, 0, nil)
547
548 #[
549 proc WriteDescriptors[TShader, TUniforms, TGlobals](renderData: RenderData, uniforms: TUniforms, globals: TGlobals) =
550 var descriptorSetWrites: seq[VkWriteDescriptorSet]
551 ForDescriptorFields(default(TShader), fieldName, descriptorType, descriptorCount, descriptorBindingNumber):
552 for frameInFlight in 0 ..< renderData.descriptorSets.len:
553 when descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
554 when HasGPUValueField[TUniforms](fieldName):
555 WithGPUValueField(uniforms, fieldName, gpuValue):
556 let bufferInfo = VkDescriptorBufferInfo(
557 buffer: gpuValue.buffer.vk,
558 offset: gpuValue.buffer.offset,
559 range: gpuValue.buffer.size,
560 )
561 descriptorSetWrites.add VkWriteDescriptorSet(
562 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
563 dstSet: renderData.descriptorSets[frameInFlight],
564 dstBinding: descriptorBindingNumber,
565 dstArrayElement: uint32(0),
566 descriptorType: descriptorType,
567 descriptorCount: descriptorCount,
568 pImageInfo: nil,
569 pBufferInfo: addr(bufferInfo),
570 )
571 elif HasGPUValueField[TGlobals](fieldName):
572 WithGPUValueField(globals, fieldName, theValue):
573 let bufferInfo = VkDescriptorBufferInfo(
574 buffer: theValue.buffer.vk,
575 offset: theValue.buffer.offset,
576 range: theValue.buffer.size,
577 )
578 descriptorSetWrites.add VkWriteDescriptorSet(
579 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
580 dstSet: renderData.descriptorSets[frameInFlight],
581 dstBinding: descriptorBindingNumber,
582 dstArrayElement: uint32(0),
583 descriptorType: descriptorType,
584 descriptorCount: descriptorCount,
585 pImageInfo: nil,
586 pBufferInfo: addr(bufferInfo),
587 )
588 else:
589 {.error: "Unable to find field '" & fieldName & "' in uniforms or globals".}
590 elif descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
591 # TODO
592 let imageInfo = VkDescriptorImageInfo(
593 sampler: VkSampler(0),
594 imageView: VkImageView(0),
595 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
596 )
597 descriptorSetWrites.add VkWriteDescriptorSet(
598 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
599 dstSet: renderData.descriptorSets[frameInFlight],
600 dstBinding: descriptorBindingNumber,
601 dstArrayElement: 0'u32,
602 descriptorType: descriptorType,
603 descriptorCount: descriptorCount,
604 pImageInfo: addr(imageInfo),
605 pBufferInfo: nil,
606 )
607 else:
608 assert false, "Unsupported descriptor type"
609 vkUpdateDescriptorSets(vulkan.device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil)
610 ]#
611
612 559
613 converter toVkIndexType(indexType: IndexType): VkIndexType = 560 converter toVkIndexType(indexType: IndexType): VkIndexType =
614 case indexType: 561 case indexType:
615 of None: VK_INDEX_TYPE_NONE_KHR 562 of None: VK_INDEX_TYPE_NONE_KHR
616 of UInt8: VK_INDEX_TYPE_UINT8_EXT 563 of UInt8: VK_INDEX_TYPE_UINT8_EXT
1021 if size > biggestHeap: 968 if size > biggestHeap:
1022 biggestHeap = size 969 biggestHeap = size
1023 memoryTypeIndex = i 970 memoryTypeIndex = i
1024 971
1025 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" 972 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type"
1026 var allocationInfo = VkMemoryAllocateInfo( 973 result.vk = svkAllocateMemory(result.size, memoryTypeIndex)
1027 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1028 allocationSize: result.size,
1029 memoryTypeIndex: memoryTypeIndex,
1030 )
1031 checkVkResult vkAllocateMemory(
1032 vulkan.device,
1033 addr allocationInfo,
1034 nil,
1035 addr result.vk
1036 )
1037 974
1038 proc AllocateDirectMemory(size: uint64): DirectGPUMemory = 975 proc AllocateDirectMemory(size: uint64): DirectGPUMemory =
1039 result.size = size 976 result.size = size
1040 result.needsFlush = true 977 result.needsFlush = true
1041 978
1054 biggestHeap = size 991 biggestHeap = size
1055 memoryTypeIndex = i 992 memoryTypeIndex = i
1056 result.needsFlush = not (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in flags) 993 result.needsFlush = not (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in flags)
1057 994
1058 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" 995 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type"
1059 var allocationInfo = VkMemoryAllocateInfo( 996 result.vk = svkAllocateMemory(result.size, GetDirectMemoryTypeIndex())
1060 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1061 allocationSize: result.size,
1062 memoryTypeIndex: GetDirectMemoryTypeIndex(),
1063 )
1064 checkVkResult vkAllocateMemory(
1065 vulkan.device,
1066 addr allocationInfo,
1067 nil,
1068 addr result.vk
1069 )
1070 checkVkResult vkMapMemory( 997 checkVkResult vkMapMemory(
1071 device = vulkan.device, 998 device = vulkan.device,
1072 memory = result.vk, 999 memory = result.vk,
1073 offset = 0'u64, 1000 offset = 0'u64,
1074 size = result.size, 1001 size = result.size,
1086 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 1013 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
1087 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 1014 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
1088 1015
1089 # iterate through memory areas to find big enough free space 1016 # iterate through memory areas to find big enough free space
1090 # TODO: dynamically expand memory allocations 1017 # TODO: dynamically expand memory allocations
1018 # TODO: use RequiredMemorySize()
1091 for (memory, usedOffset) in renderData.indirectMemory.mitems: 1019 for (memory, usedOffset) in renderData.indirectMemory.mitems:
1092 if memory.size - usedOffset >= size: 1020 if memory.size - usedOffset >= size:
1093 buffer.offset = usedOffset 1021 buffer.offset = usedOffset
1094 # create buffer 1022 # create buffer
1095 var createInfo = VkBufferCreateInfo( 1023 buffer.vk = svkCreateBuffer(buffer.size, usageFlags)
1096 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1097 flags: VkBufferCreateFlags(0),
1098 size: buffer.size,
1099 usage: toBits(usageFlags),
1100 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
1101 )
1102 checkVkResult vkCreateBuffer(
1103 device = vulkan.device,
1104 pCreateInfo = addr createInfo,
1105 pAllocator = nil,
1106 pBuffer = addr(buffer.vk)
1107 )
1108 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset) 1024 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset)
1109 renderData.indirectBuffers.add (buffer, btype, 0'u64) 1025 renderData.indirectBuffers.add (buffer, btype, 0'u64)
1110 # update memory area offset 1026 # update memory area offset
1111 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT) 1027 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1112 return 1028 return
1124 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 1040 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
1125 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 1041 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
1126 1042
1127 # iterate through memory areas to find big enough free space 1043 # iterate through memory areas to find big enough free space
1128 # TODO: dynamically expand memory allocations 1044 # TODO: dynamically expand memory allocations
1045 # TODO: use RequiredMemorySize()
1129 for (memory, usedOffset) in renderData.directMemory.mitems: 1046 for (memory, usedOffset) in renderData.directMemory.mitems:
1130 if memory.size - usedOffset >= size: 1047 if memory.size - usedOffset >= size:
1131 buffer.offset = usedOffset 1048 buffer.offset = usedOffset
1132 # create buffer 1049 buffer.vk = svkCreateBuffer(buffer.size, usageFlags)
1133 var createInfo = VkBufferCreateInfo(
1134 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1135 flags: VkBufferCreateFlags(0),
1136 size: buffer.size,
1137 usage: toBits(usageFlags),
1138 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
1139 )
1140 checkVkResult vkCreateBuffer(
1141 device = vulkan.device,
1142 pCreateInfo = addr createInfo,
1143 pAllocator = nil,
1144 pBuffer = addr(buffer.vk)
1145 )
1146 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset) 1050 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset)
1147 renderData.directBuffers.add (buffer, btype, 0'u64) 1051 renderData.directBuffers.add (buffer, btype, 0'u64)
1148 # update memory area offset 1052 # update memory area offset
1149 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT) 1053 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1150 return 1054 return
1252 break 1156 break
1253 assert foundBuffer, &"Unable to find large enough '{btype}' for '{data}'" 1157 assert foundBuffer, &"Unable to find large enough '{btype}' for '{data}'"
1254 proc AssignDirectBuffers(renderdata: var RenderData, btype: BufferType, data: var DescriptorSet) = 1158 proc AssignDirectBuffers(renderdata: var RenderData, btype: BufferType, data: var DescriptorSet) =
1255 AssignDirectBuffers(renderdata, btype, data.data) 1159 AssignDirectBuffers(renderdata, btype, data.data)
1256 1160
1161 proc TransitionImageLayout(image: VkImage, oldLayout, newLayout: VkImageLayout) =
1162 var
1163 barrier = VkImageMemoryBarrier(
1164 sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1165 oldLayout: oldLayout,
1166 newLayout: newLayout,
1167 srcQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED,
1168 dstQueueFamilyIndex: VK_QUEUE_FAMILY_IGNORED,
1169 image: image,
1170 subresourceRange: VkImageSubresourceRange(
1171 aspectMask: toBits [VK_IMAGE_ASPECT_COLOR_BIT],
1172 baseMipLevel: 0,
1173 levelCount: 1,
1174 baseArrayLayer: 0,
1175 layerCount: 1,
1176 ),
1177 )
1178 srcStage: VkPipelineStageFlagBits
1179 dstStage: VkPipelineStageFlagBits
1180
1181 if oldLayout == VK_IMAGE_LAYOUT_UNDEFINED and newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
1182 srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
1183 barrier.srcAccessMask = VkAccessFlags(0)
1184 dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT
1185 barrier.dstAccessMask = [VK_ACCESS_TRANSFER_WRITE_BIT].toBits
1186 elif oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL and newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
1187 srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT
1188 barrier.srcAccessMask = [VK_ACCESS_TRANSFER_WRITE_BIT].toBits
1189 dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
1190 barrier.dstAccessMask = [VK_ACCESS_SHADER_READ_BIT].toBits
1191 else:
1192 raise newException(Exception, "Unsupported layout transition!")
1193
1194 WithSingleUseCommandBuffer(commandBuffer):
1195 vkCmdPipelineBarrier(
1196 commandBuffer,
1197 srcStageMask = [srcStage].toBits,
1198 dstStageMask = [dstStage].toBits,
1199 dependencyFlags = VkDependencyFlags(0),
1200 memoryBarrierCount = 0,
1201 pMemoryBarriers = nil,
1202 bufferMemoryBarrierCount = 0,
1203 pBufferMemoryBarriers = nil,
1204 imageMemoryBarrierCount = 1,
1205 pImageMemoryBarriers = addr(barrier),
1206 )
1207
1208 proc createImageView(image: VkImage, format: VkFormat): VkImageView =
1209 var createInfo = VkImageViewCreateInfo(
1210 sType: VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1211 image: image,
1212 viewType: VK_IMAGE_VIEW_TYPE_2D,
1213 format: format,
1214 components: VkComponentMapping(
1215 r: VK_COMPONENT_SWIZZLE_IDENTITY,
1216 g: VK_COMPONENT_SWIZZLE_IDENTITY,
1217 b: VK_COMPONENT_SWIZZLE_IDENTITY,
1218 a: VK_COMPONENT_SWIZZLE_IDENTITY,
1219 ),
1220 subresourceRange: VkImageSubresourceRange(
1221 aspectMask: VkImageAspectFlags(VK_IMAGE_ASPECT_COLOR_BIT),
1222 baseMipLevel: 0,
1223 levelCount: 1,
1224 baseArrayLayer: 0,
1225 layerCount: 1,
1226 ),
1227 )
1228 checkVkResult vkCreateImageView(vulkan.device, addr(createInfo), nil, addr(result))
1229
1230 proc createSampler(
1231 magFilter = VK_FILTER_LINEAR,
1232 minFilter = VK_FILTER_LINEAR,
1233 addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
1234 addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
1235 ): VkSampler =
1236
1237 let samplerInfo = VkSamplerCreateInfo(
1238 sType: VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1239 magFilter: magFilter,
1240 minFilter: minFilter,
1241 addressModeU: addressModeU,
1242 addressModeV: addressModeV,
1243 addressModeW: VK_SAMPLER_ADDRESS_MODE_REPEAT,
1244 anisotropyEnable: vulkan.anisotropy > 0,
1245 maxAnisotropy: vulkan.anisotropy,
1246 borderColor: VK_BORDER_COLOR_INT_OPAQUE_BLACK,
1247 unnormalizedCoordinates: VK_FALSE,
1248 compareEnable: VK_FALSE,
1249 compareOp: VK_COMPARE_OP_ALWAYS,
1250 mipmapMode: VK_SAMPLER_MIPMAP_MODE_LINEAR,
1251 mipLodBias: 0,
1252 minLod: 0,
1253 maxLod: 0,
1254 )
1255 checkVkResult vkCreateSampler(vulkan.device, addr(samplerInfo), nil, addr(result))
1256
1257 proc createTextureImage(renderData: var RenderData, texture: var Texture) =
1258 assert texture.vk == VkImage(0)
1259 assert texture.offset == 0
1260 const usage = [VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_USAGE_SAMPLED_BIT]
1261
1262 texture.format = GetVkFormat(texture.depth, usage = usage)
1263 texture.vk = svkCreate2DImage(texture.width, texture.height, texture.format, usage)
1264 let size = texture.vk.RequiredMemorySize()
1265
1266 when genericParams(typeof(texture)).get(1) is IndirectGPUMemory:
1267 for (memory, usedOffset) in renderData.indirectMemory.mitems:
1268 if memory.size - usedOffset >= size:
1269 texture.memory = memory
1270 texture.offset = usedOffset
1271 # update memory area offset
1272 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1273 break
1274 elif genericParams(typeof(texture)).get(1) is DirectGPUMemory:
1275 for (memory, usedOffset) in renderData.directMemory.mitems:
1276 if memory.size - usedOffset >= size:
1277 texture.memory = memory
1278 texture.offset = usedOffset
1279 # update memory area offset
1280 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1281 break
1282
1283 checkVkResult vkBindImageMemory(
1284 vulkan.device,
1285 texture.vk,
1286 texture.memory.vk,
1287 texture.offset,
1288 )
1289
1290 # data transfer and layout transition
1291 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
1292 WithStagingBuffer((texture.vk, texture.imageview, texture.width, texture.height), size, GetDirectMemoryTypeIndex(), stagingPtr):
1293 copyMem(stagingPtr, texture.data.ToCPointer, size)
1294 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
1295
1296 texture.imageview = createImageView(texture.vk, texture.format)
1297 texture.sampler = createSampler()
1298
1299 proc UploadTextures(renderdata: var RenderData, descriptorSet: var DescriptorSet) =
1300 for name, value in fieldPairs(descriptorSet.data):
1301 when typeof(value) is Texture:
1302 renderdata.createTextureImage(value)
1303
1257 proc HasGPUValueField[T](name: static string): bool {.compileTime.} = 1304 proc HasGPUValueField[T](name: static string): bool {.compileTime.} =
1258 for fieldname, value in default(T).fieldPairs(): 1305 for fieldname, value in default(T).fieldPairs():
1259 when typeof(value) is GPUValue and fieldname == name: return true 1306 when typeof(value) is GPUValue and fieldname == name: return true
1260 return false 1307 return false
1261 1308
1378 objPosition: GPUArray[Vec3f, IndirectGPUMemory] 1425 objPosition: GPUArray[Vec3f, IndirectGPUMemory]
1379 MaterialA = object 1426 MaterialA = object
1380 reflection: float32 1427 reflection: float32
1381 baseColor: Vec3f 1428 baseColor: Vec3f
1382 UniformsA = object 1429 UniformsA = object
1383 defaultTexture: Texture[3, IndirectGPUMemory] 1430 defaultTexture: Texture[TVec3[uint8], IndirectGPUMemory]
1384 defaultMaterial: GPUValue[MaterialA, IndirectGPUMemory] 1431 defaultMaterial: GPUValue[MaterialA, IndirectGPUMemory]
1385 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory] 1432 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory]
1386 materialTextures: array[3, Texture[3, IndirectGPUMemory]] 1433 materialTextures: array[3, Texture[TVec3[uint8], IndirectGPUMemory]]
1387 ShaderSettings = object 1434 ShaderSettings = object
1388 gamma: float32 1435 gamma: float32
1389 GlobalsA = object 1436 GlobalsA = object
1390 fontAtlas: Texture[1, IndirectGPUMemory] 1437 fontAtlas: Texture[TVec3[uint8], IndirectGPUMemory]
1391 settings: GPUValue[ShaderSettings, IndirectGPUMemory] 1438 settings: GPUValue[ShaderSettings, IndirectGPUMemory]
1392 1439
1393 ShaderA = object 1440 ShaderA = object
1394 # vertex input 1441 # vertex input
1395 position {.VertexAttribute.}: Vec3f 1442 position {.VertexAttribute.}: Vec3f
1445 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)), 1492 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)),
1446 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)), 1493 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)),
1447 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)), 1494 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)),
1448 ]), 1495 ]),
1449 materialTextures: [ 1496 materialTextures: [
1450 Texture[3, IndirectGPUMemory](), 1497 Texture[TVec3[uint8], IndirectGPUMemory](),
1451 Texture[3, IndirectGPUMemory](), 1498 Texture[TVec3[uint8], IndirectGPUMemory](),
1452 Texture[3, IndirectGPUMemory](), 1499 Texture[TVec3[uint8], IndirectGPUMemory](),
1453 ] 1500 ]
1454 ) 1501 )
1455 ) 1502 )
1456 var instances1 = InstanceA( 1503 var instances1 = InstanceA(
1457 rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]), 1504 rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]),
1467 let shaderObject = CompileShader(shader) 1514 let shaderObject = CompileShader(shader)
1468 var pipeline1 = CreatePipeline(renderPass = renderpass, shader = shaderObject) 1515 var pipeline1 = CreatePipeline(renderPass = renderpass, shader = shaderObject)
1469 1516
1470 var renderdata = InitRenderData() 1517 var renderdata = InitRenderData()
1471 1518
1472 # TODO: Textures
1473 # upload all textures
1474 # write descriptors for textures and uniform buffers
1475
1476 # buffer allocation 1519 # buffer allocation
1477 var
1478 indirectVertexSizes = 0'u64
1479 directVertexSizes = 0'u64
1480 indirectIndexSizes = 0'u64
1481 directIndexSizes = 0'u64
1482 indirectUniformSizes = 0'u64
1483 directUniformSizes = 0'u64
1484
1485 # buffer allocation
1486
1487 echo "Allocating GPU buffers" 1520 echo "Allocating GPU buffers"
1521
1522 var indirectVertexSizes = 0'u64
1488 indirectVertexSizes += GetIndirectBufferSizes(myMesh1) 1523 indirectVertexSizes += GetIndirectBufferSizes(myMesh1)
1489 indirectVertexSizes += GetIndirectBufferSizes(instances1) 1524 indirectVertexSizes += GetIndirectBufferSizes(instances1)
1490 AllocateIndirectBuffer(renderdata, indirectVertexSizes, VertexBuffer) 1525 AllocateIndirectBuffer(renderdata, indirectVertexSizes, VertexBuffer)
1491 1526
1527 var directVertexSizes = 0'u64
1492 directVertexSizes += GetDirectBufferSizes(myMesh1) 1528 directVertexSizes += GetDirectBufferSizes(myMesh1)
1493 directVertexSizes += GetDirectBufferSizes(instances1) 1529 directVertexSizes += GetDirectBufferSizes(instances1)
1494 AllocateDirectBuffer(renderdata, directVertexSizes, VertexBuffer) 1530 AllocateDirectBuffer(renderdata, directVertexSizes, VertexBuffer)
1495 1531
1532 var indirectIndexSizes = 0'u64
1496 indirectIndexSizes += GetIndirectIndexBufferSizes(myMesh1) 1533 indirectIndexSizes += GetIndirectIndexBufferSizes(myMesh1)
1497 AllocateIndirectBuffer(renderdata, indirectIndexSizes, IndexBuffer) 1534 AllocateIndirectBuffer(renderdata, indirectIndexSizes, IndexBuffer)
1498 1535
1536 var directIndexSizes = 0'u64
1499 directIndexSizes += GetDirectIndexBufferSizes(myMesh1) 1537 directIndexSizes += GetDirectIndexBufferSizes(myMesh1)
1500 AllocateDirectBuffer(renderdata, directIndexSizes, IndexBuffer) 1538 AllocateDirectBuffer(renderdata, directIndexSizes, IndexBuffer)
1501 1539
1540 var indirectUniformSizes = 0'u64
1502 indirectUniformSizes += GetIndirectBufferSizes(uniforms1) 1541 indirectUniformSizes += GetIndirectBufferSizes(uniforms1)
1503 indirectUniformSizes += GetIndirectBufferSizes(myGlobals) 1542 indirectUniformSizes += GetIndirectBufferSizes(myGlobals)
1504 AllocateIndirectBuffer(renderdata, indirectUniformSizes, UniformBuffer) 1543 AllocateIndirectBuffer(renderdata, indirectUniformSizes, UniformBuffer)
1505 1544
1545 var directUniformSizes = 0'u64
1506 directUniformSizes += GetDirectBufferSizes(uniforms1) 1546 directUniformSizes += GetDirectBufferSizes(uniforms1)
1507 directUniformSizes += GetDirectBufferSizes(myGlobals) 1547 directUniformSizes += GetDirectBufferSizes(myGlobals)
1508 AllocateDirectBuffer(renderdata, directUniformSizes, UniformBuffer) 1548 AllocateDirectBuffer(renderdata, directUniformSizes, UniformBuffer)
1509 1549
1550
1510 # buffer assignment 1551 # buffer assignment
1511 #
1512 echo "Assigning buffers to GPUData fields" 1552 echo "Assigning buffers to GPUData fields"
1513 1553
1514 # for meshes we do: 1554 # for meshes we do:
1515 renderdata.AssignIndirectBuffers(VertexBuffer, myMesh1) 1555 renderdata.AssignIndirectBuffers(VertexBuffer, myMesh1)
1516 renderdata.AssignDirectBuffers(VertexBuffer, myMesh1) 1556 renderdata.AssignDirectBuffers(VertexBuffer, myMesh1)
1525 renderdata.AssignIndirectBuffers(UniformBuffer, uniforms1) 1565 renderdata.AssignIndirectBuffers(UniformBuffer, uniforms1)
1526 renderdata.AssignDirectBuffers(UniformBuffer, uniforms1) 1566 renderdata.AssignDirectBuffers(UniformBuffer, uniforms1)
1527 renderdata.AssignIndirectBuffers(UniformBuffer, myGlobals) 1567 renderdata.AssignIndirectBuffers(UniformBuffer, myGlobals)
1528 renderdata.AssignDirectBuffers(UniformBuffer, myGlobals) 1568 renderdata.AssignDirectBuffers(UniformBuffer, myGlobals)
1529 1569
1530 # buffer filling 1570 renderdata.UploadTextures(uniforms1)
1531 1571 renderdata.UploadTextures(myGlobals)
1572
1573 echo uniforms1.data.materialTextures
1574
1575
1576 # copy everything to GPU
1532 echo "Copying all data to GPU memory" 1577 echo "Copying all data to GPU memory"
1533
1534 # copy everything to GPU
1535 UpdateAllGPUBuffers(myMesh1) 1578 UpdateAllGPUBuffers(myMesh1)
1536 UpdateAllGPUBuffers(instances1) 1579 UpdateAllGPUBuffers(instances1)
1537 UpdateAllGPUBuffers(uniforms1) 1580 UpdateAllGPUBuffers(uniforms1)
1538 UpdateAllGPUBuffers(myGlobals) 1581 UpdateAllGPUBuffers(myGlobals)
1539 renderdata.FlushDirectMemory() 1582 renderdata.FlushDirectMemory()
1540 1583
1541 1584
1542 # descriptors 1585 # descriptors
1543 # TODO: I think we can write and assign descriptors directly after creation 1586 echo "Writing descriptors"
1544 InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[GlobalSet], myGlobals) 1587 InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[GlobalSet], myGlobals)
1545 InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[MaterialSet], uniforms1) 1588 InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[MaterialSet], uniforms1)
1546 # WriteDescriptors[ShaderA, UniformsA, GlobalsA](renderdata, uniforms1, myGlobals)
1547 1589
1548 1590
1549 # command buffer 1591 # command buffer
1550 var 1592 var
1551 commandBufferPool: VkCommandPool 1593 commandBufferPool: VkCommandPool