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)]), |