Mercurial > games > semicongine
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) |