Mercurial > games > semicongine
comparison static_utils.nim @ 1175:a94732d98cc6 compiletime-tests
merge
| author | sam <sam@basx.dev> |
|---|---|
| date | Sat, 29 Jun 2024 11:13:35 +0700 |
| parents | fafc2f14da0b |
| children | 511c9f7cd1da |
comparison
equal
deleted
inserted
replaced
| 1174:26e367076c15 | 1175:a94732d98cc6 |
|---|---|
| 123 let `fieldname` {.inject.} = theFieldname | 123 let `fieldname` {.inject.} = theFieldname |
| 124 let `valuename` {.inject.} = value | 124 let `valuename` {.inject.} = value |
| 125 let `isinstancename` {.inject.} = hasCustomPragma(value, InstanceAttribute) | 125 let `isinstancename` {.inject.} = hasCustomPragma(value, InstanceAttribute) |
| 126 body | 126 body |
| 127 | 127 |
| 128 template ForDescriptorFields*(inputData: typed, typename, countname, body: untyped): untyped = | 128 template ForDescriptorFields*(inputData: typed, typename, countname, bindingNumber, body: untyped): untyped = |
| 129 var `bindingNumber` {.inject.} = 1'u32 | |
| 129 for theFieldname, value in fieldPairs(inputData): | 130 for theFieldname, value in fieldPairs(inputData): |
| 130 when typeof(value) is Texture: | 131 when typeof(value) is Texture: |
| 131 block: | 132 block: |
| 132 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER | 133 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER |
| 133 let `countname` {.inject.} = 1'u32 | 134 let `countname` {.inject.} = 1'u32 |
| 134 body | 135 body |
| 136 `bindingNumber`.inc | |
| 135 elif typeof(value) is object: | 137 elif typeof(value) is object: |
| 136 block: | 138 block: |
| 137 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER | 139 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER |
| 138 let `countname` {.inject.} = 1'u32 | 140 let `countname` {.inject.} = 1'u32 |
| 139 body | 141 body |
| 142 `bindingNumber`.inc | |
| 140 elif typeof(value) is array: | 143 elif typeof(value) is array: |
| 141 when elementType(value) is Texture: | 144 when elementType(value) is Texture: |
| 142 block: | 145 block: |
| 143 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER | 146 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER |
| 144 let `countname` {.inject.} = uint32(typeof(value).len) | 147 let `countname` {.inject.} = uint32(typeof(value).len) |
| 145 body | 148 body |
| 149 `bindingNumber`.inc | |
| 146 elif elementType(value) is object: | 150 elif elementType(value) is object: |
| 147 block: | 151 block: |
| 148 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER | 152 let `typename` {.inject.} = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER |
| 149 let `countname` {.inject.} = uint32(typeof(value).len) | 153 let `countname` {.inject.} = uint32(typeof(value).len) |
| 150 body | 154 body |
| 155 `bindingNumber`.inc | |
| 151 | 156 |
| 152 func NumberOfVertexInputAttributeDescriptors[T: SupportedGPUType|Texture](value: T): uint32 = | 157 func NumberOfVertexInputAttributeDescriptors[T: SupportedGPUType|Texture](value: T): uint32 = |
| 153 when T is TMat2[float32] or T is TMat2[float64] or T is TMat23[float32] or T is TMat23[float64]: | 158 when T is TMat2[float32] or T is TMat2[float64] or T is TMat23[float32] or T is TMat23[float64]: |
| 154 2 | 159 2 |
| 155 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]: | 160 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]: |
| 205 indexCount: uint32 | 210 indexCount: uint32 |
| 206 indexBufferOffset: VkDeviceSize | 211 indexBufferOffset: VkDeviceSize |
| 207 Pipeline[TShader] = object | 212 Pipeline[TShader] = object |
| 208 pipeline: VkPipeline | 213 pipeline: VkPipeline |
| 209 layout: VkPipelineLayout | 214 layout: VkPipelineLayout |
| 210 descriptorSets: array[INFLIGHTFRAMES, VkDescriptorSet] | 215 descriptorSets: array[INFLIGHTFRAMES.int, VkDescriptorSet] |
| 211 | 216 |
| 212 converter toVkIndexType(indexType: IndexType): VkIndexType = | 217 converter toVkIndexType(indexType: IndexType): VkIndexType = |
| 213 case indexType: | 218 case indexType: |
| 214 of None: VK_INDEX_TYPE_NONE_KHR | 219 of None: VK_INDEX_TYPE_NONE_KHR |
| 215 of UInt8: VK_INDEX_TYPE_UINT8_EXT | 220 of UInt8: VK_INDEX_TYPE_UINT8_EXT |
| 389 uniforms & | 394 uniforms & |
| 390 samplers & | 395 samplers & |
| 391 fsOutput & | 396 fsOutput & |
| 392 @[shader.fragmentCode]).join("\n") | 397 @[shader.fragmentCode]).join("\n") |
| 393 | 398 |
| 394 # proc CompileShader[TShader](shader: static TShader): (seq[uint32], seq[uint32]) {.compileTime.}= | |
| 395 proc CompileShader[TShader](device: VkDevice, shader: static TShader): ShaderObject[TShader] = | 399 proc CompileShader[TShader](device: VkDevice, shader: static TShader): ShaderObject[TShader] = |
| 396 const (vertexShaderSource, fragmentShaderSource) = generateShaderSource(shader) | 400 const (vertexShaderSource, fragmentShaderSource) = generateShaderSource(shader) |
| 397 | 401 |
| 398 let vertexBinary = compileGlslToSPIRV(VK_SHADER_STAGE_VERTEX_BIT, vertexShaderSource) | 402 let vertexBinary = compileGlslToSPIRV(VK_SHADER_STAGE_VERTEX_BIT, vertexShaderSource) |
| 399 let fragmentBinary = compileGlslToSPIRV(VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShaderSource) | 403 let fragmentBinary = compileGlslToSPIRV(VK_SHADER_STAGE_FRAGMENT_BIT, fragmentShaderSource) |
| 426 # - we only support one subpass | 430 # - we only support one subpass |
| 427 # = we only support one Uniform-Block | 431 # = we only support one Uniform-Block |
| 428 | 432 |
| 429 # create pipeline | 433 # create pipeline |
| 430 var layoutbindings: seq[VkDescriptorSetLayoutBinding] | 434 var layoutbindings: seq[VkDescriptorSetLayoutBinding] |
| 431 var descriptorBindingNumber = 0'u32 | 435 ForDescriptorFields(default(TShader), descriptorType, descriptorCount, descriptorBindingNumber): |
| 432 ForDescriptorFields(default(TShader), descriptorType, descriptorCount): | |
| 433 layoutbindings.add VkDescriptorSetLayoutBinding( | 436 layoutbindings.add VkDescriptorSetLayoutBinding( |
| 434 binding: descriptorBindingNumber, | 437 binding: descriptorBindingNumber, |
| 435 descriptorType: descriptorType, | 438 descriptorType: descriptorType, |
| 436 descriptorCount: descriptorCount, | 439 descriptorCount: descriptorCount, |
| 437 stageFlags: VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS), | 440 stageFlags: VkShaderStageFlags(VK_SHADER_STAGE_ALL_GRAPHICS), |
| 438 pImmutableSamplers: nil, | 441 pImmutableSamplers: nil, |
| 439 ) | 442 ) |
| 440 inc descriptorBindingNumber | |
| 441 var layoutCreateInfo = VkDescriptorSetLayoutCreateInfo( | 443 var layoutCreateInfo = VkDescriptorSetLayoutCreateInfo( |
| 442 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, | 444 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, |
| 443 bindingCount: uint32(layoutbindings.len), | 445 bindingCount: uint32(layoutbindings.len), |
| 444 pBindings: layoutbindings.ToCPointer | 446 pBindings: layoutbindings.ToCPointer |
| 445 ) | 447 ) |
| 606 descriptorSetCount: uint32(layouts.len), | 608 descriptorSetCount: uint32(layouts.len), |
| 607 pSetLayouts: layouts.ToCPointer, | 609 pSetLayouts: layouts.ToCPointer, |
| 608 ) | 610 ) |
| 609 checkVkResult vkAllocateDescriptorSets(device, addr(allocInfo), result.descriptorSets.ToCPointer) | 611 checkVkResult vkAllocateDescriptorSets(device, addr(allocInfo), result.descriptorSets.ToCPointer) |
| 610 | 612 |
| 611 # write descriptor sets | 613 proc WriteDescriptors[TShader](device: VkDevice, pipeline: Pipeline[TShader]) = |
| 612 # TODO | |
| 613 #[ | |
| 614 var descriptorSetWrites: seq[VkWriteDescriptorSet] | 614 var descriptorSetWrites: seq[VkWriteDescriptorSet] |
| 615 for XY in descriptors?: | 615 ForDescriptorFields(default(TShader), descriptorType, descriptorCount, descriptorBindingNumber): |
| 616 | 616 for frameInFlight in 0 ..< pipeline.descriptorSets.len: |
| 617 bufferInfos.add VkDescriptorBufferInfo( | 617 if descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: |
| 618 buffer: descriptor.buffer.vk, | 618 # TODO |
| 619 offset: descriptor.offset, | 619 let bufferInfo = VkDescriptorBufferInfo( |
| 620 range: descriptor.size, | 620 buffer: VkBuffer(0), |
| 621 ) | 621 offset: 0, |
| 622 descriptorSetWrites.add VkWriteDescriptorSet( | 622 range: 1, |
| 623 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | 623 ) |
| 624 dstSet: descriptorSet.vk, | 624 descriptorSetWrites.add VkWriteDescriptorSet( |
| 625 dstBinding: i, | 625 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, |
| 626 dstArrayElement: 0, | 626 dstSet: pipeline.descriptorSets[frameInFlight], |
| 627 descriptorType: descriptor.vkType, | 627 dstBinding: descriptorBindingNumber, |
| 628 descriptorCount: uint32(descriptor.count), | 628 dstArrayElement: uint32(0), |
| 629 pBufferInfo: addr bufferInfos[^1], | 629 descriptorType: descriptorType, |
| 630 ) | 630 descriptorCount: descriptorCount, |
| 631 vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil) | 631 pImageInfo: nil, |
| 632 ]# | 632 pBufferInfo: addr(bufferInfo), |
| 633 | 633 ) |
| 634 elif descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: | |
| 635 # TODO | |
| 636 let imageInfo = VkDescriptorImageInfo( | |
| 637 sampler: VkSampler(0), | |
| 638 imageView: VkImageView(0), | |
| 639 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 640 ) | |
| 641 descriptorSetWrites.add VkWriteDescriptorSet( | |
| 642 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | |
| 643 dstSet: pipeline.descriptorSets[frameInFlight], | |
| 644 dstBinding: descriptorBindingNumber, | |
| 645 dstArrayElement: uint32(0), | |
| 646 descriptorType: descriptorType, | |
| 647 descriptorCount: descriptorCount, | |
| 648 pImageInfo: addr(imageInfo), | |
| 649 pBufferInfo: nil, | |
| 650 ) | |
| 651 vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil) | |
| 634 | 652 |
| 635 proc CreateRenderable[TMesh, TInstance]( | 653 proc CreateRenderable[TMesh, TInstance]( |
| 636 mesh: TMesh, | 654 mesh: TMesh, |
| 637 instance: TInstance, | 655 instance: TInstance, |
| 638 buffers: RenderBuffers, | 656 buffers: RenderBuffers, |
| 639 ): Renderable[TMesh, TInstance] = | 657 ): Renderable[TMesh, TInstance] = |
| 640 result.indexType = None | 658 result.indexType = None |
| 641 | 659 |
| 642 proc Bind[T](pipeline: Pipeline[T], commandBuffer: VkCommandBuffer, currentFrameInFlight: int) = | 660 proc Bind[T](pipeline: Pipeline[T], commandBuffer: VkCommandBuffer, currentFrameInFlight: int) = |
| 643 let a = pipeline.descriptorSets | 661 let a = pipeline.descriptorSets |
| 644 echo a[^currentFrameInFlight] | |
| 645 commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) | 662 commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) |
| 646 if a[currentFrameInFlight] != VkDescriptorSet(0): | 663 if a[currentFrameInFlight] != VkDescriptorSet(0): |
| 647 commandBuffer.vkCmdBindDescriptorSets( | 664 commandBuffer.vkCmdBindDescriptorSets( |
| 648 VK_PIPELINE_BIND_POINT_GRAPHICS, | 665 VK_PIPELINE_BIND_POINT_GRAPHICS, |
| 649 pipeline.layout, | 666 pipeline.layout, |
| 706 pipeline: Pipeline[TShader], | 723 pipeline: Pipeline[TShader], |
| 707 renderable: Renderable[TMesh, TInstance], | 724 renderable: Renderable[TMesh, TInstance], |
| 708 globals: TGlobals, | 725 globals: TGlobals, |
| 709 commandBuffer: VkCommandBuffer, | 726 commandBuffer: VkCommandBuffer, |
| 710 ) = | 727 ) = |
| 711 {.error: "Need to write descriptor sets".} | |
| 712 static: AssertCompatible(TShader, TMesh, TInstance, TGlobals) | 728 static: AssertCompatible(TShader, TMesh, TInstance, TGlobals) |
| 713 if renderable.vertexBuffers.len > 0: | 729 if renderable.vertexBuffers.len > 0: |
| 714 commandBuffer.vkCmdBindVertexBuffers( | 730 commandBuffer.vkCmdBindVertexBuffers( |
| 715 firstBinding = 0'u32, | 731 firstBinding = 0'u32, |
| 716 bindingCount = uint32(renderable.vertexBuffers.len), | 732 bindingCount = uint32(renderable.vertexBuffers.len), |
| 741 when isMainModule: | 757 when isMainModule: |
| 742 import semicongine/platform/window | 758 import semicongine/platform/window |
| 743 import semicongine/vulkan/instance | 759 import semicongine/vulkan/instance |
| 744 import semicongine/vulkan/device | 760 import semicongine/vulkan/device |
| 745 import semicongine/vulkan/physicaldevice | 761 import semicongine/vulkan/physicaldevice |
| 746 # import semicongine/vulkan/renderpass | |
| 747 import semicongine/vulkan/commandbuffer | |
| 748 import std/options | 762 import std/options |
| 749 | 763 |
| 750 type | 764 type |
| 751 MaterialA = object | 765 MaterialA = object |
| 752 reflection: float32 | 766 reflection: float32 |
| 792 layers = @["VK_LAYER_KHRONOS_validation"], | 806 layers = @["VK_LAYER_KHRONOS_validation"], |
| 793 ) | 807 ) |
| 794 | 808 |
| 795 | 809 |
| 796 let selectedPhysicalDevice = i.GetPhysicalDevices().FilterBestGraphics() | 810 let selectedPhysicalDevice = i.GetPhysicalDevices().FilterBestGraphics() |
| 797 let d = i.CreateDevice( | 811 let dev = i.CreateDevice( |
| 798 selectedPhysicalDevice, | 812 selectedPhysicalDevice, |
| 799 enabledExtensions = @[], | 813 enabledExtensions = @[], |
| 800 selectedPhysicalDevice.FilterForGraphicsPresentationQueues() | 814 selectedPhysicalDevice.FilterForGraphicsPresentationQueues() |
| 801 ) | 815 ) |
| 802 | 816 let frameWidth = 100'u32 |
| 803 var r: Renderable[MeshA, InstanceA] | 817 let frameHeight = 100'u32 |
| 804 var g: Globals | 818 |
| 805 | 819 var myRenderable: Renderable[MeshA, InstanceA] |
| 820 var myGlobals: Globals | |
| 821 | |
| 822 # setup for rendering (TODO: swapchain & framebuffers) | |
| 823 | |
| 824 # renderpass | |
| 825 let renderpass = dev.vk.CreateRenderPass(dev.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat().format) | |
| 826 | |
| 827 # shaders | |
| 806 const shader = ShaderA() | 828 const shader = ShaderA() |
| 807 let shaderObject = d.vk.CompileShader(shader) | 829 let shaderObject = dev.vk.CompileShader(shader) |
| 808 let rp = d.vk.CreateRenderPass(d.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat().format) | 830 var pipeline1 = CreatePipeline(dev.vk, renderPass = renderpass, shaderObject) |
| 809 var p = CreatePipeline(d.vk, renderPass = rp, shaderObject) | 831 |
| 810 | 832 # TODO: probably here: allocate renderables, uniform buffers & textures |
| 811 let commandBufferPool = d.CreateCommandBufferPool(d.FirstGraphicsQueue().get().family, INFLIGHTFRAMES.int) | 833 |
| 812 let cmd = commandBufferPool.buffers[0] | 834 # descriptors |
| 813 | 835 WriteDescriptors(dev.vk, pipeline1) |
| 814 checkVkResult cmd.vkResetCommandBuffer(VkCommandBufferResetFlags(0)) | 836 |
| 815 let beginInfo = VkCommandBufferBeginInfo( | 837 # command buffer |
| 816 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, | 838 var |
| 817 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), | 839 commandBufferPool: VkCommandPool |
| 840 cmdBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer] | |
| 841 createInfo = VkCommandPoolCreateInfo( | |
| 842 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, | |
| 843 flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT], | |
| 844 queueFamilyIndex: dev.FirstGraphicsQueue().get().family.index, | |
| 845 ) | |
| 846 checkVkResult vkCreateCommandPool(dev.vk, addr createInfo, nil, addr commandBufferPool) | |
| 847 var allocInfo = VkCommandBufferAllocateInfo( | |
| 848 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, | |
| 849 commandPool: commandBufferPool, | |
| 850 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, | |
| 851 commandBufferCount: INFLIGHTFRAMES, | |
| 818 ) | 852 ) |
| 819 checkVkResult cmd.vkBeginCommandBuffer(addr(beginInfo)) | 853 checkVkResult vkAllocateCommandBuffers(dev.vk, addr allocInfo, cmdBuffers.ToCPointer) |
| 820 Bind(p, cmd, currentFrameInFlight = 0) | 854 |
| 821 Render(p, r, g, cmd) | 855 # start command buffer |
| 822 | 856 block: |
| 823 checkVkResult cmd.vkEndCommandBuffer() | 857 let |
| 858 currentFramebuffer = VkFramebuffer(0) # TODO | |
| 859 currentFrameInFlight = 1 | |
| 860 cmd = cmdBuffers[currentFrameInFlight] | |
| 861 beginInfo = VkCommandBufferBeginInfo( | |
| 862 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, | |
| 863 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), | |
| 864 ) | |
| 865 checkVkResult cmd.vkResetCommandBuffer(VkCommandBufferResetFlags(0)) | |
| 866 checkVkResult cmd.vkBeginCommandBuffer(addr(beginInfo)) | |
| 867 | |
| 868 # start renderpass | |
| 869 block: | |
| 870 var | |
| 871 clearColors = [VkClearValue(color: VkClearColorValue(float32: [0, 0, 0, 0]))] | |
| 872 renderPassInfo = VkRenderPassBeginInfo( | |
| 873 sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, | |
| 874 renderPass: renderpass, | |
| 875 framebuffer: currentFramebuffer, | |
| 876 renderArea: VkRect2D( | |
| 877 offset: VkOffset2D(x: 0, y: 0), | |
| 878 extent: VkExtent2D(width: frameWidth, height: frameHeight), | |
| 879 ), | |
| 880 clearValueCount: uint32(clearColors.len), | |
| 881 pClearValues: clearColors.ToCPointer(), | |
| 882 ) | |
| 883 viewport = VkViewport( | |
| 884 x: 0.0, | |
| 885 y: 0.0, | |
| 886 width: frameWidth.float32, | |
| 887 height: frameHeight.float32, | |
| 888 minDepth: 0.0, | |
| 889 maxDepth: 1.0, | |
| 890 ) | |
| 891 scissor = VkRect2D( | |
| 892 offset: VkOffset2D(x: 0, y: 0), | |
| 893 extent: VkExtent2D(width: frameWidth, height: frameHeight) | |
| 894 ) | |
| 895 vkCmdBeginRenderPass(cmd, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE) | |
| 896 | |
| 897 # setup viewport | |
| 898 vkCmdSetViewport(cmd, firstViewport = 0, viewportCount = 1, addr(viewport)) | |
| 899 vkCmdSetScissor(cmd, firstScissor = 0, scissorCount = 1, addr(scissor)) | |
| 900 | |
| 901 # bind pipeline, will be loop | |
| 902 block: | |
| 903 Bind(pipeline1, cmd, currentFrameInFlight = currentFrameInFlight) | |
| 904 | |
| 905 # render object, will be loop | |
| 906 block: | |
| 907 Render(pipeline1, myRenderable, myGlobals, cmd) | |
| 908 | |
| 909 vkCmdEndRenderPass(cmd) | |
| 910 checkVkResult cmd.vkEndCommandBuffer() |
