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