comparison semiconginev2/rendering/renderer.nim @ 1254:b0f4c8ccd49a

did: stuff to test gltf importer
author sam <sam@basx.dev>
date Sat, 27 Jul 2024 20:47:54 +0700
parents c4f98eb4bb05
children 2b5ca798f6d6
comparison
equal deleted inserted replaced
1253:c4f98eb4bb05 1254:b0f4c8ccd49a
531 elif typeof(value) is array: 531 elif typeof(value) is array:
532 when elementType(value) is Image: 532 when elementType(value) is Image:
533 for image in value.mitems: 533 for image in value.mitems:
534 renderdata.createVulkanImage(image) 534 renderdata.createVulkanImage(image)
535 535
536 proc HasGPUValueField[T](name: static string): bool {.compileTime.} = 536 type EMPTY = object # only used for static assertions
537 for fieldname, value in default(T).fieldPairs(): 537
538 when typeof(value) is GPUValue and fieldname == name: return true 538 proc assertAllDescriptorsBound(A, B, C, D, TShader: typedesc) =
539 return false 539 var foundDescriptorSets = false
540 540 for attrName, attrValue in default(TShader).fieldPairs():
541 template WithGPUValueField(obj: object, name: static string, fieldvalue, body: untyped): untyped = 541 when hasCustomPragma(attrValue, DescriptorSets):
542 # HasGPUValueField MUST be used to check if this is supported 542 assert not foundDescriptorSets, "Only one shader attribute is allowed to have the pragma 'DescriptorSets'"
543 for fieldname, value in obj.fieldPairs(): 543 when not (A is EMPTY): assert typeof(attrValue[0]) is A
544 when fieldname == name: 544 when not (B is EMPTY): assert typeof(attrValue[1]) is B
545 block: 545 when not (C is EMPTY): assert typeof(attrValue[2]) is C
546 let `fieldvalue` {.inject.} = value 546 when not (D is EMPTY): assert typeof(attrValue[3]) is D
547 body 547
548 548 var hasBoundDescriptorSets {.compileTime.} = false # okay, I am not sure if this is clean, unproblematic or sane. Just trying to get some comptime-validation
549 template WithBind*[A, B, C, D](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], DescriptorSet[B], DescriptorSet[C], DescriptorSet[D]), pipeline: Pipeline, body: untyped): untyped = 549 var hasDescriptorSets {.compileTime} = false
550
551 template WithBind*[A, B, C, D, TShader](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], DescriptorSet[B], DescriptorSet[C], DescriptorSet[D]), pipeline: Pipeline[TShader], body: untyped): untyped =
552 static: assertAllDescriptorsBound(A, B, C, D, TShader)
550 block: 553 block:
551 var descriptorSets: seq[VkDescriptorSet] 554 var descriptorSets: seq[VkDescriptorSet]
552 for dSet in sets.fields: 555 for dSet in sets.fields:
553 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet" 556 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet"
554 descriptorSets.add dSet.vk[currentFiF()] 557 descriptorSets.add dSet.vk[currentFiF()]
555 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout) 558 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout)
559 static:
560 assert not hasBoundDescriptorSets, "Cannot call WithBind nested"
561 hasBoundDescriptorSets = true
556 body 562 body
557 template WithBind*[A, B, C](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], DescriptorSet[B], DescriptorSet[C]), pipeline: Pipeline, body: untyped): untyped = 563 static:
564 hasBoundDescriptorSets = false
565 template WithBind*[A, B, C, TShader](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], DescriptorSet[B], DescriptorSet[C]), pipeline: Pipeline[TShader], body: untyped): untyped =
566 static: assertAllDescriptorsBound(A, B, C, EMPTY, TShader)
558 block: 567 block:
559 var descriptorSets: seq[VkDescriptorSet] 568 var descriptorSets: seq[VkDescriptorSet]
560 for dSet in sets.fields: 569 for dSet in sets.fields:
561 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet" 570 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet"
562 descriptorSets.add dSet.vk[currentFiF()] 571 descriptorSets.add dSet.vk[currentFiF()]
563 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout) 572 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout)
573 static:
574 assert not hasBoundDescriptorSets, "Cannot call WithBind nested"
575 hasBoundDescriptorSets = true
564 body 576 body
565 template WithBind*[A, B](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], DescriptorSet[B]), pipeline: Pipeline, body: untyped): untyped = 577 static:
578 hasBoundDescriptorSets = false
579 template WithBind*[A, B, TShader](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], DescriptorSet[B]), pipeline: Pipeline[TShader], body: untyped): untyped =
580 static: assertAllDescriptorsBound(A, B, EMPTY, EMPTY, TShader)
566 block: 581 block:
567 var descriptorSets: seq[VkDescriptorSet] 582 var descriptorSets: seq[VkDescriptorSet]
568 for dSet in sets.fields: 583 for dSet in sets.fields:
569 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet" 584 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet"
570 descriptorSets.add dSet.vk[currentFiF()] 585 descriptorSets.add dSet.vk[currentFiF()]
571 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout) 586 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout)
587 static:
588 assert not hasBoundDescriptorSets, "Cannot call WithBind nested"
589 hasBoundDescriptorSets = true
572 body 590 body
573 template WithBind*[A](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], ), pipeline: Pipeline, body: untyped): untyped = 591 static:
592 hasBoundDescriptorSets = false
593 template WithBind*[A, TShader](commandBuffer: VkCommandBuffer, sets: (DescriptorSet[A], ), pipeline: Pipeline[TShader], body: untyped): untyped =
594 static: assertAllDescriptorsBound(A, EMPTY, EMPTY, EMPTY, TShader)
574 block: 595 block:
575 var descriptorSets: seq[VkDescriptorSet] 596 var descriptorSets: seq[VkDescriptorSet]
576 for dSet in sets.fields: 597 for dSet in sets.fields:
577 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet" 598 assert dSet.vk[currentFiF()].Valid, "DescriptorSet not initialized, maybe forgot to call InitDescriptorSet"
578 descriptorSets.add dSet.vk[currentFiF()] 599 descriptorSets.add dSet.vk[currentFiF()]
579 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout) 600 svkCmdBindDescriptorSets(commandBuffer, descriptorSets, pipeline.layout)
601 static:
602 assert not hasBoundDescriptorSets, "Cannot call WithBind nested"
603 hasBoundDescriptorSets = true
580 body 604 body
605 static:
606 hasBoundDescriptorSets = false
607
608 proc assertCanRenderMesh(TShader, TMesh, TInstance: typedesc) =
609 for attrName, attrValue in default(TShader).fieldPairs:
610 if hasCustomPragma(attrValue, VertexAttribute):
611 var foundAttr = false
612 for meshAttrName, meshAttrValue in default(TMesh).fieldPairs:
613 if attrName == meshAttrName:
614 assert typeof(meshAttrValue) is GPUArray, "Mesh attribute '" & attrName & "' must be a GPUArray"
615 assert typeof(attrValue) is elementType(meshAttrValue.data), "Type of shader attribute and mesh attribute '" & attrName & "' is not the same"
616 foundAttr = true
617 assert foundAttr, "Attribute '" & attrName & "' is not provided in mesh type '" & name(TMesh) & "'"
618 if hasCustomPragma(attrValue, InstanceAttribute):
619 var foundAttr = false
620 for instAttrName, instAttrValue in default(TInstance).fieldPairs:
621 if attrName == instAttrName:
622 assert typeof(instAttrValue) is GPUArray, "Instance attribute '" & attrName & "' must be a GPUArray"
623 assert foundAttr == false, "Attribute '" & attrName & "' is defined in Mesh and Instance, can only be one"
624 assert typeof(attrValue) is elementType(instAttrValue.data), "Type of shader attribute and mesh attribute '" & attrName & "' is not the same"
625 foundAttr = true
626 assert foundAttr, "Attribute '" & attrName & "' is not provided in instance type '" & name(TInstance) & "'"
581 627
582 proc Render*[TShader, TMesh, TInstance]( 628 proc Render*[TShader, TMesh, TInstance](
583 commandBuffer: VkCommandBuffer, 629 commandBuffer: VkCommandBuffer,
584 pipeline: Pipeline[TShader], 630 pipeline: Pipeline[TShader],
585 mesh: TMesh, 631 mesh: TMesh,
586 instances: TInstance, 632 instances: TInstance,
587 ) = 633 ) =
634
635 static: assertCanRenderMesh(TShader, TMesh, TInstance)
636 static:
637 hasDescriptorSets = false
638 for attrName, attrValue in default(TShader).fieldPairs():
639 if attrValue.hasCustomPragma(DescriptorSets):
640 hasDescriptorSets = true
641 if hasDescriptorSets:
642 assert hasBoundDescriptorSets, "Shader uses descriptor sets, but none are bound"
588 643
589 var vertexBuffers: seq[VkBuffer] 644 var vertexBuffers: seq[VkBuffer]
590 var vertexBuffersOffsets: seq[uint64] 645 var vertexBuffersOffsets: seq[uint64]
591 var elementCount = 0'u32 646 var elementCount = 0'u32
592 var instanceCount = 1'u32 647 var instanceCount = 1'u32
658 vertexCount = elementCount, 713 vertexCount = elementCount,
659 instanceCount = instanceCount, 714 instanceCount = instanceCount,
660 firstVertex = 0, 715 firstVertex = 0,
661 firstInstance = 0 716 firstInstance = 0
662 ) 717 )
663
664 type EMPTY = object
665 718
666 proc Render*[TShader, TMesh]( 719 proc Render*[TShader, TMesh](
667 commandBuffer: VkCommandBuffer, 720 commandBuffer: VkCommandBuffer,
668 pipeline: Pipeline[TShader], 721 pipeline: Pipeline[TShader],
669 mesh: TMesh, 722 mesh: TMesh,