comparison static_utils.nim @ 1185:565fcfde427a compiletime-tests

did: first seemingly working version of texture/descriptor stuff
author sam <sam@basx.dev>
date Sat, 06 Jul 2024 15:05:28 +0700
parents 3f43c7163029
children 52e926efaac5
comparison
equal deleted inserted replaced
1184:3f43c7163029 1185:565fcfde427a
42 size: uint64 42 size: uint64
43 needsTransfer: bool # usually true 43 needsTransfer: bool # usually true
44 DirectGPUMemory = object 44 DirectGPUMemory = object
45 vk: VkDeviceMemory 45 vk: VkDeviceMemory
46 size: uint64 46 size: uint64
47 data: pointer 47 rawPointer: pointer
48 needsFlush: bool # usually true
49 GPUMemory = IndirectGPUMemory | DirectGPUMemory 48 GPUMemory = IndirectGPUMemory | DirectGPUMemory
50 49
51 Buffer[TMemory: GPUMemory] = object 50 Buffer[TMemory: GPUMemory] = object
51 vk: VkBuffer
52 size: uint64
53 rawPointer: pointer
54 Texture[T: TextureType, TMemory: GPUMemory] = object
55 vk: VkImage
52 memory: TMemory 56 memory: TMemory
53 vk: VkBuffer
54 offset: uint64
55 size: uint64
56 Texture[T: TextureType, TMemory: GPUMemory] = object
57 memory: TMemory
58 vk: VkImage
59 format: VkFormat 57 format: VkFormat
60 imageview: VkImageView 58 imageview: VkImageView
61 sampler: VkSampler 59 sampler: VkSampler
62 offset: uint64 60 offset: uint64
63 size: uint64 61 size: uint64
99 func size(texture: Texture): uint64 = 97 func size(texture: Texture): uint64 =
100 texture.data.len * sizeof(elementType(texture.data)) 98 texture.data.len * sizeof(elementType(texture.data))
101 99
102 func depth(texture: Texture): int = 100 func depth(texture: Texture): int =
103 default(elementType(texture.data)).len 101 default(elementType(texture.data)).len
102
103 func pointerOffset[T: SomeInteger](p: pointer, offset: T): pointer =
104 cast[pointer](cast[T](p) + offset)
105
104 106
105 proc GetVkFormat(depth: int, usage: openArray[VkImageUsageFlagBits]): VkFormat = 107 proc GetVkFormat(depth: int, usage: openArray[VkImageUsageFlagBits]): VkFormat =
106 const DEPTH_FORMAT_MAP = [ 108 const DEPTH_FORMAT_MAP = [
107 0: [VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED], 109 0: [VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED],
108 1: [VK_FORMAT_R8_SRGB, VK_FORMAT_R8_UNORM], 110 1: [VK_FORMAT_R8_SRGB, VK_FORMAT_R8_UNORM],
328 template size(gpuArray: GPUArray): uint64 = 330 template size(gpuArray: GPUArray): uint64 =
329 (gpuArray.data.len * sizeof(elementType(gpuArray.data))).uint64 331 (gpuArray.data.len * sizeof(elementType(gpuArray.data))).uint64
330 template size(gpuValue: GPUValue): uint64 = 332 template size(gpuValue: GPUValue): uint64 =
331 sizeof(gpuValue.data).uint64 333 sizeof(gpuValue.data).uint64
332 334
333 template datapointer(gpuArray: GPUArray): pointer = 335 template rawPointer(gpuArray: GPUArray): pointer =
334 addr(gpuArray.data[0]) 336 addr(gpuArray.data[0])
335 template datapointer(gpuValue: GPUValue): pointer = 337 template rawPointer(gpuValue: GPUValue): pointer =
336 addr(gpuValue.data) 338 addr(gpuValue.data)
337 339
338 proc RequiredMemorySize(buffer: VkBuffer): uint64 = 340 proc RequiredMemorySize(buffer: VkBuffer): uint64 =
339 var req: VkMemoryRequirements 341 var req: VkMemoryRequirements
340 vkGetBufferMemoryRequirements(vulkan.device, buffer, addr(req)) 342 vkGetBufferMemoryRequirements(vulkan.device, buffer, addr(req))
368 result = pDevice 370 result = pDevice
369 371
370 assert score > 0, "Unable to find integrated or discrete GPU" 372 assert score > 0, "Unable to find integrated or discrete GPU"
371 373
372 374
373 proc GetDirectMemoryTypeIndex(): uint32 = 375 proc GetDirectMemoryType(): uint32 =
374 var physicalProperties: VkPhysicalDeviceMemoryProperties 376 var physicalProperties: VkPhysicalDeviceMemoryProperties
375 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr(physicalProperties)) 377 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr(physicalProperties))
376 378
377 var biggestHeap: uint64 = 0 379 var biggestHeap: uint64 = 0
378 result = high(uint32) 380 result = high(uint32)
394 for i in 0'u32 ..< nQueuefamilies: 396 for i in 0'u32 ..< nQueuefamilies:
395 if qType in toEnums(queuFamilies[i].queueFlags): 397 if qType in toEnums(queuFamilies[i].queueFlags):
396 return i 398 return i
397 assert false, &"Queue of type {qType} not found" 399 assert false, &"Queue of type {qType} not found"
398 400
399 proc GetQueue(device: VkDevice, queueFamilyIndex: uint32, qType: VkQueueFlagBits): VkQueue =
400 vkGetDeviceQueue(
401 device,
402 queueFamilyIndex,
403 0,
404 addr(result),
405 )
406
407 proc GetSurfaceFormat(): VkFormat = 401 proc GetSurfaceFormat(): VkFormat =
408 # EVERY windows driver and almost every linux driver should support this 402 # EVERY windows driver and almost every linux driver should support this
409 VK_FORMAT_B8G8R8A8_SRGB 403 VK_FORMAT_B8G8R8A8_SRGB
410
411 template WithSingleUseCommandBuffer(cmd, body: untyped): untyped =
412 block:
413 var
414 commandBufferPool: VkCommandPool
415 createInfo = VkCommandPoolCreateInfo(
416 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
417 flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
418 queueFamilyIndex: vulkan.queueFamilyIndex,
419 )
420 checkVkResult vkCreateCommandPool(vulkan.device, addr createInfo, nil, addr(commandBufferPool))
421 var
422 `cmd` {.inject.}: VkCommandBuffer
423 allocInfo = VkCommandBufferAllocateInfo(
424 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
425 commandPool: commandBufferPool,
426 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
427 commandBufferCount: 1,
428 )
429 checkVkResult vulkan.device.vkAllocateCommandBuffers(addr allocInfo, addr(`cmd`))
430 var beginInfo = VkCommandBufferBeginInfo(
431 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
432 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
433 )
434 checkVkResult `cmd`.vkBeginCommandBuffer(addr beginInfo)
435
436 body
437
438 checkVkResult `cmd`.vkEndCommandBuffer()
439 var submitInfo = VkSubmitInfo(
440 sType: VK_STRUCTURE_TYPE_SUBMIT_INFO,
441 commandBufferCount: 1,
442 pCommandBuffers: addr(`cmd`),
443 )
444
445 var
446 fence: VkFence
447 fenceInfo = VkFenceCreateInfo(
448 sType: VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
449 # flags: toBits [VK_FENCE_CREATE_SIGNALED_BIT]
450 )
451 checkVkResult vulkan.device.vkCreateFence(addr(fenceInfo), nil, addr(fence))
452 checkVkResult vkQueueSubmit(vulkan.queue, 1, addr(submitInfo), fence)
453 checkVkResult vkWaitForFences(vulkan.device, 1, addr fence, false, high(uint64))
454 vkDestroyCommandPool(vulkan.device, commandBufferPool, nil)
455
456 404
457 proc UpdateGPUBuffer(gpuData: GPUData) = 405 proc UpdateGPUBuffer(gpuData: GPUData) =
458 if gpuData.size == 0: 406 if gpuData.size == 0:
459 return 407 return
460 when UsesDirectMemory(gpuData): 408 when UsesDirectMemory(gpuData):
461 copyMem(cast[pointer](cast[uint64](gpuData.buffer.memory.data) + gpuData.buffer.offset + gpuData.offset), gpuData.datapointer, gpuData.size) 409 copyMem(pointerOffset(gpuData.buffer.rawPointer, gpuData.offset), gpuData.rawPointer, gpuData.size)
462 else: 410 else:
463 WithStagingBuffer(gpuData.buffer.vk, gpuData.buffer.vk.RequiredMemorySize(), GetDirectMemoryTypeIndex(), stagingPtr): 411 WithStagingBuffer((gpuData.buffer.vk, gpuData.offset), gpuData.buffer.vk.RequiredMemorySize(), GetDirectMemoryType(), stagingPtr):
464 copyMem(stagingPtr, gpuData.datapointer, gpuData.size) 412 copyMem(stagingPtr, gpuData.rawPointer, gpuData.size)
465 413
466 proc UpdateAllGPUBuffers[T](value: T) = 414 proc UpdateAllGPUBuffers[T](value: T) =
467 for name, fieldvalue in value.fieldPairs(): 415 for name, fieldvalue in value.fieldPairs():
468 when typeof(fieldvalue) is GPUData: 416 when typeof(fieldvalue) is GPUData:
469 UpdateGPUBuffer(fieldvalue) 417 UpdateGPUBuffer(fieldvalue)
479 assert value.buffer.vk.Valid 427 assert value.buffer.vk.Valid
480 # TODO: 428 # TODO:
481 # when typeof(value) is Texture: 429 # when typeof(value) is Texture:
482 # assert value.texture.vk.Valid 430 # assert value.texture.vk.Valid
483 431
432 # TODO: missing stuff here? only for FiF, but not multiple different sets?
484 # allocate 433 # allocate
485 var layouts = newSeqWith(descriptorSet.vk.len, layout) 434 var layouts = newSeqWith(descriptorSet.vk.len, layout)
486 var allocInfo = VkDescriptorSetAllocateInfo( 435 var allocInfo = VkDescriptorSetAllocateInfo(
487 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 436 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
488 descriptorPool: renderData.descriptorPool, 437 descriptorPool: renderData.descriptorPool,
489 descriptorSetCount: uint32(layouts.len), 438 descriptorSetCount: uint32(layouts.len),
490 pSetLayouts: layouts.ToCPointer, 439 pSetLayouts: layouts.ToCPointer,
491 ) 440 )
492 checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer) 441 checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer)
493 442
494 # write 443 # allocate seq with high cap to prevent realocation while adding to set
444 # (which invalidates pointers that are passed to the vulkan api call)
495 var descriptorSetWrites = newSeqOfCap[VkWriteDescriptorSet](1024) 445 var descriptorSetWrites = newSeqOfCap[VkWriteDescriptorSet](1024)
496 var imageWrites = newSeqOfCap[VkDescriptorImageInfo](1024) 446 var imageWrites = newSeqOfCap[VkDescriptorImageInfo](1024)
497 var bufferWrites = newSeqOfCap[VkDescriptorBufferInfo](1024) 447 var bufferWrites = newSeqOfCap[VkDescriptorBufferInfo](1024)
498 448
499 ForDescriptorFields(descriptorSet.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber): 449 ForDescriptorFields(descriptorSet.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber):
500 for i in 0 ..< descriptorSet.vk.len: 450 for i in 0 ..< descriptorSet.vk.len:
501 when typeof(fieldValue) is GPUValue: 451 when typeof(fieldValue) is GPUValue:
502 bufferWrites.add VkDescriptorBufferInfo( 452 bufferWrites.add VkDescriptorBufferInfo(
503 buffer: fieldValue.buffer.vk, 453 buffer: fieldValue.buffer.vk,
504 offset: fieldValue.buffer.offset, 454 offset: fieldValue.offset,
505 range: fieldValue.buffer.size, 455 range: fieldValue.size,
506 ) 456 )
507 descriptorSetWrites.add VkWriteDescriptorSet( 457 descriptorSetWrites.add VkWriteDescriptorSet(
508 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 458 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
509 dstSet: descriptorSet.vk[i], 459 dstSet: descriptorSet.vk[i],
510 dstBinding: descriptorBindingNumber, 460 dstBinding: descriptorBindingNumber,
531 pBufferInfo: nil, 481 pBufferInfo: nil,
532 ) 482 )
533 elif typeof(fieldValue) is array: 483 elif typeof(fieldValue) is array:
534 discard 484 discard
535 when elementType(fieldValue) is Texture: 485 when elementType(fieldValue) is Texture:
536 echo "Add texture array descriptor set write for set " & $i & " " & fieldName
537 for textureIndex in 0 ..< descriptorCount: 486 for textureIndex in 0 ..< descriptorCount:
538 imageWrites.add VkDescriptorImageInfo( 487 imageWrites.add VkDescriptorImageInfo(
539 sampler: fieldValue[textureIndex].sampler, 488 sampler: fieldValue[textureIndex].sampler,
540 imageView: fieldValue[textureIndex].imageView, 489 imageView: fieldValue[textureIndex].imageView,
541 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 490 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
545 dstSet: descriptorSet.vk[i], 494 dstSet: descriptorSet.vk[i],
546 dstBinding: descriptorBindingNumber, 495 dstBinding: descriptorBindingNumber,
547 dstArrayElement: 0, 496 dstArrayElement: 0,
548 descriptorType: descriptorType, 497 descriptorType: descriptorType,
549 descriptorCount: descriptorCount, 498 descriptorCount: descriptorCount,
550 pImageInfo: addr(imageWrites[^fieldValue.len]), 499 pImageInfo: addr(imageWrites[^descriptorCount.int]),
551 pBufferInfo: nil, 500 pBufferInfo: nil,
552 ) 501 )
553 else: 502 else:
554 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).} 503 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).}
555 else: 504 else:
556 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).} 505 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).}
557 506
558 vkUpdateDescriptorSets(vulkan.device, descriptorSetWrites.len.uint32, descriptorSetWrites.ToCPointer, 0, nil) 507 vkUpdateDescriptorSets(
508 device = vulkan.device,
509 descriptorWriteCount = descriptorSetWrites.len.uint32,
510 pDescriptorWrites = descriptorSetWrites.ToCPointer,
511 descriptorCopyCount = 0,
512 pDescriptorCopies = nil,
513 )
559 514
560 converter toVkIndexType(indexType: IndexType): VkIndexType = 515 converter toVkIndexType(indexType: IndexType): VkIndexType =
561 case indexType: 516 case indexType:
562 of None: VK_INDEX_TYPE_NONE_KHR 517 of None: VK_INDEX_TYPE_NONE_KHR
563 of UInt8: VK_INDEX_TYPE_UINT8_EXT 518 of UInt8: VK_INDEX_TYPE_UINT8_EXT
972 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" 927 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type"
973 result.vk = svkAllocateMemory(result.size, memoryTypeIndex) 928 result.vk = svkAllocateMemory(result.size, memoryTypeIndex)
974 929
975 proc AllocateDirectMemory(size: uint64): DirectGPUMemory = 930 proc AllocateDirectMemory(size: uint64): DirectGPUMemory =
976 result.size = size 931 result.size = size
977 result.needsFlush = true
978 932
979 # find a good memory type 933 # find a good memory type
980 var physicalProperties: VkPhysicalDeviceMemoryProperties 934 var physicalProperties: VkPhysicalDeviceMemoryProperties
981 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr physicalProperties) 935 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr physicalProperties)
982 936
988 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags: 942 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags:
989 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size 943 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size
990 if size > biggestHeap: 944 if size > biggestHeap:
991 biggestHeap = size 945 biggestHeap = size
992 memoryTypeIndex = i 946 memoryTypeIndex = i
993 result.needsFlush = not (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in flags)
994 947
995 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" 948 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type"
996 result.vk = svkAllocateMemory(result.size, GetDirectMemoryTypeIndex()) 949 result.vk = svkAllocateMemory(result.size, GetDirectMemoryType())
997 checkVkResult vkMapMemory( 950 checkVkResult vkMapMemory(
998 device = vulkan.device, 951 device = vulkan.device,
999 memory = result.vk, 952 memory = result.vk,
1000 offset = 0'u64, 953 offset = 0'u64,
1001 size = result.size, 954 size = result.size,
1002 flags = VkMemoryMapFlags(0), 955 flags = VkMemoryMapFlags(0),
1003 ppData = addr(result.data) 956 ppData = addr(result.rawPointer)
1004 ) 957 )
1005 958
1006 proc AllocateIndirectBuffer(renderData: var RenderData, size: uint64, btype: BufferType) = 959 proc AllocateIndirectBuffer(renderData: var RenderData, size: uint64, btype: BufferType) =
1007 if size == 0: 960 if size == 0:
1008 return 961 return
1009 var buffer = Buffer[IndirectGPUMemory](size: size) 962 var buffer = Buffer[IndirectGPUMemory](size: size, rawPointer: nil)
1010 963
1011 let usageFlags = case btype: 964 let usageFlags = case btype:
1012 of VertexBuffer: [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 965 of VertexBuffer: [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
1013 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 966 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
1014 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 967 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
1016 # iterate through memory areas to find big enough free space 969 # iterate through memory areas to find big enough free space
1017 # TODO: dynamically expand memory allocations 970 # TODO: dynamically expand memory allocations
1018 # TODO: use RequiredMemorySize() 971 # TODO: use RequiredMemorySize()
1019 for (memory, usedOffset) in renderData.indirectMemory.mitems: 972 for (memory, usedOffset) in renderData.indirectMemory.mitems:
1020 if memory.size - usedOffset >= size: 973 if memory.size - usedOffset >= size:
1021 buffer.offset = usedOffset
1022 # create buffer 974 # create buffer
1023 buffer.vk = svkCreateBuffer(buffer.size, usageFlags) 975 buffer.vk = svkCreateBuffer(buffer.size, usageFlags)
1024 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset) 976 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, usedOffset)
1025 renderData.indirectBuffers.add (buffer, btype, 0'u64) 977 renderData.indirectBuffers.add (buffer, btype, 0'u64)
1026 # update memory area offset 978 # update memory area offset
1027 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT) 979 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1028 return 980 return
1029 981
1043 # iterate through memory areas to find big enough free space 995 # iterate through memory areas to find big enough free space
1044 # TODO: dynamically expand memory allocations 996 # TODO: dynamically expand memory allocations
1045 # TODO: use RequiredMemorySize() 997 # TODO: use RequiredMemorySize()
1046 for (memory, usedOffset) in renderData.directMemory.mitems: 998 for (memory, usedOffset) in renderData.directMemory.mitems:
1047 if memory.size - usedOffset >= size: 999 if memory.size - usedOffset >= size:
1048 buffer.offset = usedOffset
1049 buffer.vk = svkCreateBuffer(buffer.size, usageFlags) 1000 buffer.vk = svkCreateBuffer(buffer.size, usageFlags)
1050 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, buffer.offset) 1001 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, usedOffset)
1002 buffer.rawPointer = pointerOffset(memory.rawPointer, usedOffset)
1051 renderData.directBuffers.add (buffer, btype, 0'u64) 1003 renderData.directBuffers.add (buffer, btype, 0'u64)
1052 # update memory area offset 1004 # update memory area offset
1053 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT) 1005 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1054 return 1006 return
1055 1007
1287 texture.offset, 1239 texture.offset,
1288 ) 1240 )
1289 1241
1290 # data transfer and layout transition 1242 # data transfer and layout transition
1291 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) 1243 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): 1244 WithStagingBuffer((texture.vk, texture.imageview, texture.width, texture.height), size, GetDirectMemoryType(), stagingPtr):
1293 copyMem(stagingPtr, texture.data.ToCPointer, size) 1245 copyMem(stagingPtr, texture.data.ToCPointer, size)
1294 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) 1246 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
1295 1247
1296 texture.imageview = createImageView(texture.vk, texture.format) 1248 texture.imageview = createImageView(texture.vk, texture.format)
1297 texture.sampler = createSampler() 1249 texture.sampler = createSampler()
1298 1250
1299 proc UploadTextures(renderdata: var RenderData, descriptorSet: var DescriptorSet) = 1251 proc UploadTextures(renderdata: var RenderData, descriptorSet: var DescriptorSet) =
1300 for name, value in fieldPairs(descriptorSet.data): 1252 for name, value in fieldPairs(descriptorSet.data):
1301 when typeof(value) is Texture: 1253 when typeof(value) is Texture:
1254 echo "Upload texture '", name, "'"
1302 renderdata.createTextureImage(value) 1255 renderdata.createTextureImage(value)
1256 elif typeof(value) is array:
1257 when elementType(value) is Texture:
1258 echo "Upload texture ARRAY '", name, "'"
1259 for texture in value.mitems:
1260 renderdata.createTextureImage(texture)
1303 1261
1304 proc HasGPUValueField[T](name: static string): bool {.compileTime.} = 1262 proc HasGPUValueField[T](name: static string): bool {.compileTime.} =
1305 for fieldname, value in default(T).fieldPairs(): 1263 for fieldname, value in default(T).fieldPairs():
1306 when typeof(value) is GPUValue and fieldname == name: return true 1264 when typeof(value) is GPUValue and fieldname == name: return true
1307 return false 1265 return false
1478 vulkan = VulkanGlobals( 1436 vulkan = VulkanGlobals(
1479 instance: theInstance.vk, 1437 instance: theInstance.vk,
1480 device: dev, 1438 device: dev,
1481 physicalDevice: pDevice, 1439 physicalDevice: pDevice,
1482 queueFamilyIndex: qfi, 1440 queueFamilyIndex: qfi,
1483 queue: dev.GetQueue(qfi, VK_QUEUE_GRAPHICS_BIT) 1441 queue: svkGetDeviceQueue(dev, qfi, VK_QUEUE_GRAPHICS_BIT)
1484 ) 1442 )
1485 1443
1486 var myMesh1 = MeshA( 1444 var myMesh1 = MeshA(
1487 position: GPUArray[Vec3f, IndirectGPUMemory](data: @[NewVec3f(0, 0, ), NewVec3f(0, 0, ), NewVec3f(0, 0, )]), 1445 position: GPUArray[Vec3f, IndirectGPUMemory](data: @[NewVec3f(0, 0, ), NewVec3f(0, 0, ), NewVec3f(0, 0, )]),
1488 ) 1446 )
1489 var uniforms1 = DescriptorSet[UniformsA, MaterialSet]( 1447 var uniforms1 = DescriptorSet[UniformsA, MaterialSet](
1490 data: UniformsA( 1448 data: UniformsA(
1449 defaultTexture: Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1491 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory](data: [ 1450 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory](data: [
1492 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)), 1451 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)),
1493 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)), 1452 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)),
1494 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)), 1453 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)),
1495 ]), 1454 ]),
1496 materialTextures: [ 1455 materialTextures: [
1497 Texture[TVec3[uint8], IndirectGPUMemory](), 1456 Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1498 Texture[TVec3[uint8], IndirectGPUMemory](), 1457 Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1499 Texture[TVec3[uint8], IndirectGPUMemory](), 1458 Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1500 ] 1459 ]
1501 ) 1460 )
1502 ) 1461 )
1503 var instances1 = InstanceA( 1462 var instances1 = InstanceA(
1504 rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]), 1463 rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]),
1505 objPosition: GPUArray[Vec3f, IndirectGPUMemory](data: @[NewVec3f(0, 0, 0), NewVec3f(1, 1, 1)]), 1464 objPosition: GPUArray[Vec3f, IndirectGPUMemory](data: @[NewVec3f(0, 0, 0), NewVec3f(1, 1, 1)]),
1506 ) 1465 )
1507 var myGlobals = DescriptorSet[GlobalsA, GlobalSet]() 1466 var myGlobals = DescriptorSet[GlobalsA, GlobalSet](
1467 data: GlobalsA(
1468 fontAtlas: Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1469 settings: GPUValue[ShaderSettings, IndirectGPUMemory](data: ShaderSettings(gamma: 1.0))
1470 )
1471 )
1508 1472
1509 # setup for rendering (TODO: swapchain & framebuffers) 1473 # setup for rendering (TODO: swapchain & framebuffers)
1510 let renderpass = CreateRenderPass(GetSurfaceFormat()) 1474 let renderpass = CreateRenderPass(GetSurfaceFormat())
1511 1475
1512 # shaders 1476 # shaders
1565 renderdata.AssignIndirectBuffers(UniformBuffer, uniforms1) 1529 renderdata.AssignIndirectBuffers(UniformBuffer, uniforms1)
1566 renderdata.AssignDirectBuffers(UniformBuffer, uniforms1) 1530 renderdata.AssignDirectBuffers(UniformBuffer, uniforms1)
1567 renderdata.AssignIndirectBuffers(UniformBuffer, myGlobals) 1531 renderdata.AssignIndirectBuffers(UniformBuffer, myGlobals)
1568 renderdata.AssignDirectBuffers(UniformBuffer, myGlobals) 1532 renderdata.AssignDirectBuffers(UniformBuffer, myGlobals)
1569 1533
1534 renderdata.UploadTextures(myGlobals)
1570 renderdata.UploadTextures(uniforms1) 1535 renderdata.UploadTextures(uniforms1)
1571 renderdata.UploadTextures(myGlobals)
1572
1573 echo uniforms1.data.materialTextures
1574
1575 1536
1576 # copy everything to GPU 1537 # copy everything to GPU
1577 echo "Copying all data to GPU memory" 1538 echo "Copying all data to GPU memory"
1578 UpdateAllGPUBuffers(myMesh1) 1539 UpdateAllGPUBuffers(myMesh1)
1579 UpdateAllGPUBuffers(instances1) 1540 UpdateAllGPUBuffers(instances1)