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