comparison tests/test_rendering.nim @ 1498:d3d667bbdda4 default tip

did: add support for per-frame-buffers, still need to limit this, to maybe only mapped buffers
author sam <sam@basx.dev>
date Thu, 25 Sep 2025 23:53:41 +0700
parents 676fc13685a9
children
comparison
equal deleted inserted replaced
1497:56aa8fe70e9e 1498:d3d667bbdda4
8 8
9 import ../semicongine 9 import ../semicongine
10 import ../semicongine/rendering 10 import ../semicongine/rendering
11 import ../semicongine/input 11 import ../semicongine/input
12 import ../semicongine/loaders 12 import ../semicongine/loaders
13 import ../semicongine/images
13 14
14 proc test_01_triangle(time: float32, renderPass: RenderPass) = 15 proc test_01_triangle(time: float32, renderPass: RenderPass) =
15 var renderdata = initRenderData() 16 var renderdata = initRenderData()
16 17
17 type 18 type
372 ], 373 ],
373 ) 374 )
374 ) 375 )
375 var otherset1 = asDescriptorSetData( 376 var otherset1 = asDescriptorSetData(
376 OtherSet( 377 OtherSet(
377 objectSettings: 378 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 0), UniformBufferMapped)
378 asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 0), UniformBufferMapped)
379 ) 379 )
380 ) 380 )
381 var otherset2 = asDescriptorSetData( 381 var otherset2 = asDescriptorSetData(
382 OtherSet( 382 OtherSet(
383 objectSettings: 383 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 1), UniformBufferMapped)
384 asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 1), UniformBufferMapped)
385 ) 384 )
386 ) 385 )
387 386
388 assignBuffers(renderdata, quad) 387 assignBuffers(renderdata, quad)
389 assignBuffers(renderdata, constset) 388 assignBuffers(renderdata, constset)
398 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], constset) 397 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], constset)
399 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[1], mainset) 398 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[1], mainset)
400 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset1) 399 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset1)
401 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset2) 400 initDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset2)
402 401
402 updateGPUBuffer(otherset2.data[0].objectSettings, frame=0)
403 updateGPUBuffer(otherset2.data[1].objectSettings, frame=1)
404
403 var start = getMonoTime() 405 var start = getMonoTime()
404 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: 406 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
407
408 mainset.data[currentFiF()].renderSettings.data.brigthness = ((getMonoTime() - start).inMilliseconds().int / 1000) / time
409 otherset1.data[currentFiF()].objectSettings.data.scale = 0.5 + ((getMonoTime() - start).inMilliseconds().int / 1000) / time
410 updateGPUBuffer(mainset.data[currentFiF()].renderSettings, frame=currentFiF())
411 updateGPUBuffer(otherset1.data[currentFiF()].objectSettings, frame=currentFiF())
412 updateGPUBuffer(otherset2.data[currentFiF()].objectSettings, frame=currentFiF())
413 renderdata.flushAllMemory()
414
405 withNextFrame(framebuffer, commandbuffer): 415 withNextFrame(framebuffer, commandbuffer):
406 bindDescriptorSet(commandbuffer, constset, 0, pipeline) 416 bindDescriptorSet(commandbuffer, constset, 0, pipeline)
407 bindDescriptorSet(commandbuffer, mainset, 1, pipeline) 417 bindDescriptorSet(commandbuffer, mainset, 1, pipeline)
408 418
409 withRenderPass( 419 withRenderPass(
418 bindDescriptorSet(commandbuffer, otherset1, 2, pipeline) 428 bindDescriptorSet(commandbuffer, otherset1, 2, pipeline)
419 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 429 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
420 430
421 bindDescriptorSet(commandbuffer, otherset2, 2, pipeline) 431 bindDescriptorSet(commandbuffer, otherset2, 2, pipeline)
422 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 432 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
423
424 mainset.data.renderSettings.data.brigthness =
425 ((getMonoTime() - start).inMilliseconds().int / 1000) / time
426 otherset1.data.objectSettings.data.scale =
427 0.5 + ((getMonoTime() - start).inMilliseconds().int / 1000) / time
428 updateGPUBuffer(mainset.data.renderSettings)
429 updateGPUBuffer(otherset1.data.objectSettings)
430 renderdata.flushAllMemory()
431 433
432 # cleanup 434 # cleanup
433 checkVkResult vkDeviceWaitIdle(engine().vulkan.device) 435 checkVkResult vkDeviceWaitIdle(engine().vulkan.device)
434 destroyPipeline(pipeline) 436 destroyPipeline(pipeline)
435 destroyRenderData(renderdata) 437 destroyRenderData(renderdata)
546 548
547 var start = getMonoTime() 549 var start = getMonoTime()
548 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: 550 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
549 let tStartLoop = getMonoTime() - tStart 551 let tStartLoop = getMonoTime() - tStart
550 552
551 uniforms1.data.data.data.mvp = ( 553 uniforms1.data[currentFiF()].data.data.mvp = (
552 projection(-PI / 2, getAspectRatio(), 0.01, 100) * translate(0, 0, 2) * 554 projection(-PI / 2, getAspectRatio(), 0.01, 100) * translate(0, 0, 2) *
553 rotate(PI / 4, X) * rotate( 555 rotate(PI / 4, X) * rotate(
554 PI * 0.1 * (tStartLoop.inMicroseconds() / 1_000_000), Y 556 PI * 0.1 * (tStartLoop.inMicroseconds() / 1_000_000), Y
555 ) 557 )
556 ) 558 )
557 updateGPUBuffer(uniforms1.data.data, flush = true) 559 updateGPUBuffer(uniforms1.data[currentFiF()].data, frame=currentFiF(), flush = true)
558 560
559 withNextFrame(framebuffer, commandbuffer): 561 withNextFrame(framebuffer, commandbuffer):
560 withRenderPass( 562 withRenderPass(
561 renderPass, 563 renderPass,
562 framebuffer, 564 framebuffer,
829 time: float32, depthBuffer: bool, samples: VkSampleCountFlagBits 831 time: float32, depthBuffer: bool, samples: VkSampleCountFlagBits
830 ) = 832 ) =
831 var (offscreenRP, presentRP) = 833 var (offscreenRP, presentRP) =
832 createIndirectPresentationRenderPass(depthBuffer = depthBuffer, samples = samples) 834 createIndirectPresentationRenderPass(depthBuffer = depthBuffer, samples = samples)
833 835
834 setupSwapchain(renderpass = presentRP) 836 setupSwapchain(renderpass = presentRP, vSync = false, tripleBuffering = false)
835 837
836 var renderdata = initRenderData() 838 var renderdata = initRenderData()
837 839
838 type 840 type
839 Uniforms = object 841 Uniforms = object
884 QuadMesh = object 886 QuadMesh = object
885 position: GPUArray[Vec2f, VertexBuffer] 887 position: GPUArray[Vec2f, VertexBuffer]
886 indices: GPUArray[uint16, IndexBuffer] 888 indices: GPUArray[uint16, IndexBuffer]
887 889
888 var mesh = TriangleMesh( 890 var mesh = TriangleMesh(
889 position: 891 position: asGPUArray([vec3(-0.5, -0.5), vec3(0, 0.5), vec3(0.5, -0.5)], VertexBuffer),
890 asGPUArray([vec3(-0.5, -0.5), vec3(0, 0.5), vec3(0.5, -0.5)], VertexBuffer), 892 color: asGPUArray([vec3(0, 0, 1), vec3(0, 1, 0), vec3(1, 0, 0)], VertexBuffer),
891 color: asGPUArray([vec3(0, 0, 1), vec3(0, 1, 0), vec3(1, 0, 0)], VertexBuffer),
892 ) 893 )
893 var quad = QuadMesh( 894 var quad = QuadMesh(
894 position: 895 position: asGPUArray([vec2(-1, -1), vec2(-1, 1), vec2(1, 1), vec2(1, -1)], VertexBuffer),
895 asGPUArray([vec2(-1, -1), vec2(-1, 1), vec2(1, 1), vec2(1, -1)], VertexBuffer), 896 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer),
896 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer),
897 ) 897 )
898 var uniforms1 = asDescriptorSetData( 898 var uniforms1 = asDescriptorSetData(
899 Uniforms( 899 Uniforms(
900 frameTexture: 900 frameTexture: Image[BGRA](width: frameWidth(), height: frameHeight(), isRenderTarget: true)
901 Image[BGRA](width: frameWidth(), height: frameHeight(), isRenderTarget: true)
902 ) 901 )
903 ) 902 )
904 assignBuffers(renderdata, mesh) 903 assignBuffers(renderdata, mesh)
905 assignBuffers(renderdata, quad) 904 assignBuffers(renderdata, quad)
906 uploadImages(renderdata, uniforms1) 905 uploadImages(renderdata, uniforms1)
932 checkVkResult vkBindImageMemory(engine().vulkan.device, depthImage, depthMemory, 0) 931 checkVkResult vkBindImageMemory(engine().vulkan.device, depthImage, depthMemory, 0)
933 depthImageView = svkCreate2DImageView( 932 depthImageView = svkCreate2DImageView(
934 image = depthImage, format = DEPTH_FORMAT, aspect = VK_IMAGE_ASPECT_DEPTH_BIT 933 image = depthImage, format = DEPTH_FORMAT, aspect = VK_IMAGE_ASPECT_DEPTH_BIT
935 ) 934 )
936 935
937 # create msaa images (will not use the one in the swapchain 936 # create msaa images (will not use the one in the swapchain)
938 var 937 var
939 msaaImage: VkImage 938 msaaImage: VkImage
940 msaaImageView: VkImageView 939 msaaImageView: VkImageView
941 msaaMemory: VkDeviceMemory 940 msaaMemory: VkDeviceMemory
942 if offscreenRP.samples != VK_SAMPLE_COUNT_1_BIT: 941 if offscreenRP.samples != VK_SAMPLE_COUNT_1_BIT:
946 format = SURFACE_FORMAT, 945 format = SURFACE_FORMAT,
947 usage = [VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT], 946 usage = [VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT],
948 samples = offscreenRP.samples, 947 samples = offscreenRP.samples,
949 ) 948 )
950 let requirements = svkGetImageMemoryRequirements(msaaImage) 949 let requirements = svkGetImageMemoryRequirements(msaaImage)
951 msaaMemory = svkAllocateMemory( 950 msaaMemory = svkAllocateMemory(requirements.size, bestMemory(mappable = false, filter = requirements.memoryTypes))
952 requirements.size, bestMemory(mappable = false, filter = requirements.memoryTypes)
953 )
954 checkVkResult vkBindImageMemory(engine().vulkan.device, msaaImage, msaaMemory, 0) 951 checkVkResult vkBindImageMemory(engine().vulkan.device, msaaImage, msaaMemory, 0)
955 msaaImageView = svkCreate2DImageView(image = msaaImage, format = SURFACE_FORMAT) 952 msaaImageView = svkCreate2DImageView(image = msaaImage, format = SURFACE_FORMAT)
956 953
957 var attachments: seq[VkImageView] 954 var attachments: seq[VkImageView]
958 if offscreenRP.samples == VK_SAMPLE_COUNT_1_BIT: 955 if offscreenRP.samples == VK_SAMPLE_COUNT_1_BIT:
959 if offscreenRP.depthBuffer: 956 if offscreenRP.depthBuffer:
960 attachments = @[uniforms1.data.frameTexture.imageview, depthImageView] 957 attachments = @[uniforms1.data[currentFiF()].frameTexture.imageview, depthImageView]
961 else: 958 else:
962 attachments = @[uniforms1.data.frameTexture.imageview] 959 attachments = @[uniforms1.data[currentFiF()].frameTexture.imageview]
963 else: 960 else:
964 if offscreenRP.depthBuffer: 961 if offscreenRP.depthBuffer:
965 attachments = 962 attachments = @[msaaImageView, depthImageView, uniforms1.data[currentFiF()].frameTexture.imageview]
966 @[msaaImageView, depthImageView, uniforms1.data.frameTexture.imageview]
967 else: 963 else:
968 attachments = @[msaaImageView, uniforms1.data.frameTexture.imageview] 964 attachments = @[msaaImageView, uniforms1.data[currentFiF()].frameTexture.imageview]
969 var offscreenFB = 965 var offscreenFB = svkCreateFramebuffer(offscreenRP.vk, frameWidth(), frameHeight(), attachments)
970 svkCreateFramebuffer(offscreenRP.vk, frameWidth(), frameHeight(), attachments) 966
967 renderdata.flushAllMemory()
971 968
972 var start = getMonoTime() 969 var start = getMonoTime()
973 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: 970 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
974 withNextFrame(framebuffer, commandbuffer): 971 withNextFrame(framebuffer, commandbuffer):
975 withRenderPass( 972 withRenderPass(
1022 (depthBuffer: false, samples: VK_SAMPLE_COUNT_4_BIT), 1019 (depthBuffer: false, samples: VK_SAMPLE_COUNT_4_BIT),
1023 (depthBuffer: true, samples: VK_SAMPLE_COUNT_1_BIT), 1020 (depthBuffer: true, samples: VK_SAMPLE_COUNT_1_BIT),
1024 (depthBuffer: true, samples: VK_SAMPLE_COUNT_4_BIT), 1021 (depthBuffer: true, samples: VK_SAMPLE_COUNT_4_BIT),
1025 ] 1022 ]
1026 1023
1024 #[
1027 # test normal 1025 # test normal
1026 var renderpass: RenderPass
1028 for i, (depthBuffer, samples) in renderPasses: 1027 for i, (depthBuffer, samples) in renderPasses:
1029 var renderpass = 1028 renderpass = createDirectPresentationRenderPass(depthBuffer = depthBuffer, samples = samples)
1030 createDirectPresentationRenderPass(depthBuffer = depthBuffer, samples = samples) 1029 setupSwapchain(renderpass = renderpass, vSync = false, tripleBuffering = false)
1031 setupSwapchain(renderpass = renderpass)
1032 1030
1033 # tests a simple triangle with minimalistic shader and vertex format 1031 # tests a simple triangle with minimalistic shader and vertex format
1034 test_01_triangle(time, renderpass) 1032 test_01_triangle(time, renderpass)
1035 1033
1036 # tests instanced triangles and quads, mixing meshes and instances 1034 # tests instanced triangles and quads, mixing meshes and instances
1053 test_08_texture_array(time, renderpass) 1051 test_08_texture_array(time, renderpass)
1054 1052
1055 checkVkResult vkDeviceWaitIdle(engine().vulkan.device) 1053 checkVkResult vkDeviceWaitIdle(engine().vulkan.device)
1056 destroyRenderPass(renderpass) 1054 destroyRenderPass(renderpass)
1057 clearSwapchain() 1055 clearSwapchain()
1056 ]#
1058 1057
1059 # test multiple render passes 1058 # test multiple render passes
1060 for i, (depthBuffer, samples) in renderPasses: 1059 for i, (depthBuffer, samples) in renderPasses:
1061 test_09_triangle_2pass(time, depthBuffer, samples) 1060 test_09_triangle_2pass(time, depthBuffer, samples)
1062 1061