Mercurial > games > semicongine
comparison static_utils.nim @ 1183:850450bfe2a2 compiletime-tests
sync from bedroom to office
| author | sam <sam@basx.dev> |
|---|---|
| date | Thu, 04 Jul 2024 07:30:08 +0700 |
| parents | e9a212e9cdf7 |
| children | 3f43c7163029 |
comparison
equal
deleted
inserted
replaced
| 1182:e9a212e9cdf7 | 1183:850450bfe2a2 |
|---|---|
| 6 import std/strutils | 6 import std/strutils |
| 7 import std/sequtils | 7 import std/sequtils |
| 8 import std/typetraits as tt | 8 import std/typetraits as tt |
| 9 | 9 |
| 10 import semicongine/core/utils | 10 import semicongine/core/utils |
| 11 import semicongine/core/imagetypes | |
| 12 import semicongine/core/vector | 11 import semicongine/core/vector |
| 13 import semicongine/core/matrix | 12 import semicongine/core/matrix |
| 14 import semicongine/core/vulkanapi | 13 import semicongine/core/vulkanapi |
| 15 | 14 |
| 16 template VertexAttribute {.pragma.} | 15 template VertexAttribute {.pragma.} |
| 56 Buffer[TMemory: GPUMemory] = object | 55 Buffer[TMemory: GPUMemory] = object |
| 57 memory: TMemory | 56 memory: TMemory |
| 58 vk: VkBuffer | 57 vk: VkBuffer |
| 59 offset: uint64 | 58 offset: uint64 |
| 60 size: uint64 | 59 size: uint64 |
| 60 Texture[Channels: static int, TMemory: GPUMemory] = object | |
| 61 memory: TMemory | |
| 62 vk: VkImage | |
| 63 imageview: VkImageView | |
| 64 sampler: VkSampler | |
| 65 offset: uint64 | |
| 66 size: uint64 | |
| 67 width: int | |
| 68 data: seq[array[Channels, uint8]] | |
| 61 | 69 |
| 62 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object | 70 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object |
| 63 data: seq[T] | 71 data: seq[T] |
| 64 buffer: Buffer[TMemory] | 72 buffer: Buffer[TMemory] |
| 65 offset: uint64 | 73 offset: uint64 |
| 72 DescriptorSetType = enum | 80 DescriptorSetType = enum |
| 73 GlobalSet | 81 GlobalSet |
| 74 MaterialSet | 82 MaterialSet |
| 75 DescriptorSet[T: object, sType: static DescriptorSetType] = object | 83 DescriptorSet[T: object, sType: static DescriptorSetType] = object |
| 76 data: T | 84 data: T |
| 77 vk: array[INFLIGHTFRAMES, VkDescriptorSet] | 85 vk: array[INFLIGHTFRAMES.int, VkDescriptorSet] |
| 78 | 86 |
| 79 Pipeline[TShader] = object | 87 Pipeline[TShader] = object |
| 80 vk: VkPipeline | 88 vk: VkPipeline |
| 81 layout: VkPipelineLayout | 89 layout: VkPipelineLayout |
| 82 descriptorSetLayouts: array[DescriptorSetType, VkDescriptorSetLayout] | 90 descriptorSetLayouts: array[DescriptorSetType, VkDescriptorSetLayout] |
| 195 const `fieldname` {.inject.} = theFieldname | 203 const `fieldname` {.inject.} = theFieldname |
| 196 let `valuename` {.inject.} = value | 204 let `valuename` {.inject.} = value |
| 197 const `isinstancename` {.inject.} = hasCustomPragma(value, InstanceAttribute) | 205 const `isinstancename` {.inject.} = hasCustomPragma(value, InstanceAttribute) |
| 198 body | 206 body |
| 199 | 207 |
| 200 template ForDescriptorFields(shader: typed, fieldname, typename, countname, bindingNumber, body: untyped): untyped = | 208 template ForDescriptorFields(shader: typed, fieldname, valuename, typename, countname, bindingNumber, body: untyped): untyped = |
| 201 var `bindingNumber` {.inject.} = 1'u32 | 209 var `bindingNumber` {.inject.} = 1'u32 |
| 202 for theFieldname, value in fieldPairs(shader): | 210 for theFieldname, value in fieldPairs(shader): |
| 203 when typeof(value) is Texture: | 211 when typeof(value) is Texture: |
| 204 block: | 212 block: |
| 205 const `fieldname` {.inject.} = theFieldname | 213 const `fieldname` {.inject.} = theFieldname |
| 206 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER | 214 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER |
| 207 const `countname` {.inject.} = 1'u32 | 215 const `countname` {.inject.} = 1'u32 |
| 216 let `valuename` {.inject.} = value | |
| 208 body | 217 body |
| 209 `bindingNumber`.inc | 218 `bindingNumber`.inc |
| 210 elif typeof(value) is object: | 219 elif typeof(value) is object: |
| 211 block: | 220 block: |
| 212 const `fieldname` {.inject.} = theFieldname | 221 const `fieldname` {.inject.} = theFieldname |
| 213 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER | 222 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER |
| 214 const `countname` {.inject.} = 1'u32 | 223 const `countname` {.inject.} = 1'u32 |
| 224 let `valuename` {.inject.} = value | |
| 215 body | 225 body |
| 216 `bindingNumber`.inc | 226 `bindingNumber`.inc |
| 217 elif typeof(value) is array: | 227 elif typeof(value) is array: |
| 218 when elementType(value) is Texture: | 228 when elementType(value) is Texture: |
| 219 block: | 229 block: |
| 220 const `fieldname` {.inject.} = theFieldname | 230 const `fieldname` {.inject.} = theFieldname |
| 221 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER | 231 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER |
| 222 const `countname` {.inject.} = uint32(typeof(value).len) | 232 const `countname` {.inject.} = uint32(typeof(value).len) |
| 233 let `valuename` {.inject.} = value | |
| 223 body | 234 body |
| 224 `bindingNumber`.inc | 235 `bindingNumber`.inc |
| 225 elif elementType(value) is object: | 236 elif elementType(value) is object: |
| 226 block: | 237 block: |
| 227 const `fieldname` {.inject.} = theFieldname | 238 const `fieldname` {.inject.} = theFieldname |
| 228 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER | 239 const `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER |
| 229 const `countname` {.inject.} = uint32(typeof(value).len) | 240 const `countname` {.inject.} = uint32(typeof(value).len) |
| 241 let `valuename` {.inject.} = value | |
| 230 body | 242 body |
| 231 `bindingNumber`.inc | 243 `bindingNumber`.inc |
| 244 else: | |
| 245 {.error: "Unsupported descriptor type: " & tt.name(typeof(value)).} | |
| 232 | 246 |
| 233 func NumberOfVertexInputAttributeDescriptors[T: SupportedGPUType|Texture](value: T): uint32 = | 247 func NumberOfVertexInputAttributeDescriptors[T: SupportedGPUType|Texture](value: T): uint32 = |
| 234 when T is TMat2[float32] or T is TMat2[float64] or T is TMat23[float32] or T is TMat23[float64]: | 248 when T is TMat2[float32] or T is TMat2[float64] or T is TMat23[float32] or T is TMat23[float64]: |
| 235 2 | 249 2 |
| 236 elif T is TMat32[float32] or T is TMat32[float64] or T is TMat3[float32] or T is TMat3[float64] or T is TMat34[float32] or T is TMat34[float64]: | 250 elif T is TMat32[float32] or T is TMat32[float64] or T is TMat3[float32] or T is TMat3[float64] or T is TMat34[float32] or T is TMat34[float64]: |
| 467 proc InitDescriptorSet( | 481 proc InitDescriptorSet( |
| 468 renderData: RenderData, | 482 renderData: RenderData, |
| 469 layout: VkDescriptorSetLayout, | 483 layout: VkDescriptorSetLayout, |
| 470 descriptorSet: var DescriptorSet, | 484 descriptorSet: var DescriptorSet, |
| 471 ) = | 485 ) = |
| 486 # santization checks | |
| 472 for name, value in descriptorSet.data.fieldPairs: | 487 for name, value in descriptorSet.data.fieldPairs: |
| 473 when typeof(value) is GPUValue: | 488 when typeof(value) is GPUValue: |
| 474 assert value.buffer.vk.valid | 489 assert value.buffer.vk.Valid |
| 475 # TODO: | 490 # TODO: |
| 476 # when typeof(value) is Texture: | 491 # when typeof(value) is Texture: |
| 477 # assert value.texture.vk.valid | 492 # assert value.texture.vk.Valid |
| 478 | 493 |
| 479 # allocate | 494 # allocate |
| 480 var layouts = newSeqWith(descriptorSet.vk.len, layout) | 495 var layouts = newSeqWith(descriptorSet.vk.len, layout) |
| 481 var allocInfo = VkDescriptorSetAllocateInfo( | 496 var allocInfo = VkDescriptorSetAllocateInfo( |
| 482 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, | 497 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, |
| 485 pSetLayouts: layouts.ToCPointer, | 500 pSetLayouts: layouts.ToCPointer, |
| 486 ) | 501 ) |
| 487 checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer) | 502 checkVkResult vkAllocateDescriptorSets(vulkan.device, addr(allocInfo), descriptorSet.vk.ToCPointer) |
| 488 | 503 |
| 489 # write | 504 # write |
| 490 var descriptorSetWrites: newSeq[VkWriteDescriptorSet](descriptorSet.vk.len) | 505 var descriptorSetWrites = newSeq[VkWriteDescriptorSet](descriptorSet.vk.len) |
| 491 for i in 0 ..< descriptorSet.vk.len: | 506 |
| 492 descriptorSetWrites.add | 507 var descriptorBinding = 0 |
| 508 ForDescriptorFields(descriptorSet.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber): | |
| 509 for i in 0 ..< descriptorSet.vk.len: | |
| 510 when typeof(fieldValue) is GPUValue: | |
| 511 let bufferInfo = VkDescriptorBufferInfo( | |
| 512 buffer: fieldValue.buffer.vk, | |
| 513 offset: fieldValue.buffer.offset, | |
| 514 range: fieldValue.buffer.size, | |
| 515 ) | |
| 516 descriptorSetWrites[i] = VkWriteDescriptorSet( | |
| 517 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | |
| 518 dstSet: descriptorSet.vk[i], | |
| 519 dstBinding: descriptorBindingNumber, | |
| 520 dstArrayElement: uint32(0), | |
| 521 descriptorType: descriptorType, | |
| 522 descriptorCount: descriptorCount, | |
| 523 pImageInfo: nil, | |
| 524 pBufferInfo: addr(bufferInfo), | |
| 525 ) | |
| 526 elif typeof(fieldValue) is Texture: | |
| 527 let imageInfo = VkDescriptorImageInfo( | |
| 528 sampler: fieldValue.sampler, | |
| 529 imageView: fieldValue.imageView, | |
| 530 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 531 ) | |
| 532 descriptorSetWrites[i] = VkWriteDescriptorSet( | |
| 533 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | |
| 534 dstSet: descriptorSet.vk[i], | |
| 535 dstBinding: descriptorBindingNumber, | |
| 536 dstArrayElement: uint32(0), | |
| 537 descriptorType: descriptorType, | |
| 538 descriptorCount: descriptorCount, | |
| 539 pImageInfo: addr(imageInfo), | |
| 540 pBufferInfo: nil, | |
| 541 ) | |
| 542 else: | |
| 543 {.error: "Unsupported descriptor type: " & tt.name(typeof(fieldValue)).} | |
| 493 | 544 |
| 494 | 545 |
| 495 vkUpdateDescriptorSets(vulkan.device, descriptorSetWrites.len.uint32, descriptorSetWrites.ToCPointer, 0, nil) | 546 vkUpdateDescriptorSets(vulkan.device, descriptorSetWrites.len.uint32, descriptorSetWrites.ToCPointer, 0, nil) |
| 496 | 547 |
| 497 #[ | 548 #[ |
| 787 # create pipeline | 838 # create pipeline |
| 788 | 839 |
| 789 for theFieldname, value in fieldPairs(default(TShader)): | 840 for theFieldname, value in fieldPairs(default(TShader)): |
| 790 when typeof(value) is DescriptorSet: | 841 when typeof(value) is DescriptorSet: |
| 791 var layoutbindings: seq[VkDescriptorSetLayoutBinding] | 842 var layoutbindings: seq[VkDescriptorSetLayoutBinding] |
| 792 ForDescriptorFields(value.data, fieldName, descriptorType, descriptorCount, descriptorBindingNumber): | 843 ForDescriptorFields(value.data, fieldName, fieldValue, descriptorType, descriptorCount, descriptorBindingNumber): |
| 793 layoutbindings.add VkDescriptorSetLayoutBinding( | 844 layoutbindings.add VkDescriptorSetLayoutBinding( |
| 794 binding: descriptorBindingNumber, | 845 binding: descriptorBindingNumber, |
| 795 descriptorType: descriptorType, | 846 descriptorType: descriptorType, |
| 796 descriptorCount: descriptorCount, | 847 descriptorCount: descriptorCount, |
| 797 stageFlags: VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS), | 848 stageFlags: VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS), |
| 1327 objPosition: GPUArray[Vec3f, IndirectGPUMemory] | 1378 objPosition: GPUArray[Vec3f, IndirectGPUMemory] |
| 1328 MaterialA = object | 1379 MaterialA = object |
| 1329 reflection: float32 | 1380 reflection: float32 |
| 1330 baseColor: Vec3f | 1381 baseColor: Vec3f |
| 1331 UniformsA = object | 1382 UniformsA = object |
| 1332 defaultTexture: Texture | 1383 defaultTexture: Texture[3, IndirectGPUMemory] |
| 1333 defaultMaterial: GPUValue[MaterialA, IndirectGPUMemory] | 1384 defaultMaterial: GPUValue[MaterialA, IndirectGPUMemory] |
| 1334 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory] | 1385 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory] |
| 1335 materialTextures: array[3, Texture] | 1386 materialTextures: array[3, Texture[3, IndirectGPUMemory]] |
| 1336 ShaderSettings = object | 1387 ShaderSettings = object |
| 1337 gamma: float32 | 1388 gamma: float32 |
| 1338 GlobalsA = object | 1389 GlobalsA = object |
| 1339 fontAtlas: Texture | 1390 fontAtlas: Texture[1, IndirectGPUMemory] |
| 1340 settings: GPUValue[ShaderSettings, IndirectGPUMemory] | 1391 settings: GPUValue[ShaderSettings, IndirectGPUMemory] |
| 1341 | 1392 |
| 1342 ShaderA = object | 1393 ShaderA = object |
| 1343 # vertex input | 1394 # vertex input |
| 1344 position {.VertexAttribute.}: Vec3f | 1395 position {.VertexAttribute.}: Vec3f |
| 1394 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)), | 1445 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)), |
| 1395 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)), | 1446 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)), |
| 1396 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)), | 1447 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)), |
| 1397 ]), | 1448 ]), |
| 1398 materialTextures: [ | 1449 materialTextures: [ |
| 1399 Texture(isGrayscale: false, colorImage: Image[RGBAPixel](width: 1, height: 1, imagedata: @[[255'u8, 0'u8, 0'u8, 255'u8]])), | 1450 Texture[3, IndirectGPUMemory](), |
| 1400 Texture(isGrayscale: false, colorImage: Image[RGBAPixel](width: 1, height: 1, imagedata: @[[0'u8, 255'u8, 0'u8, 255'u8]])), | 1451 Texture[3, IndirectGPUMemory](), |
| 1401 Texture(isGrayscale: false, colorImage: Image[RGBAPixel](width: 1, height: 1, imagedata: @[[0'u8, 0'u8, 255'u8, 255'u8]])), | 1452 Texture[3, IndirectGPUMemory](), |
| 1402 ] | 1453 ] |
| 1403 ) | 1454 ) |
| 1404 ) | 1455 ) |
| 1405 var instances1 = InstanceA( | 1456 var instances1 = InstanceA( |
| 1406 rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]), | 1457 rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]), |
