comparison tests/test_rendering.nim @ 1229:5dcb503ef0c0

did: refactor renderpass a bit, enable depth buffering and msaa on offscreen-rendering
author sam <sam@basx.dev>
date Thu, 18 Jul 2024 21:32:41 +0700
parents 4e465583ea32
children 51221494caeb
comparison
equal deleted inserted replaced
1228:4e465583ea32 1229:5dcb503ef0c0
1 import std/options 1 import std/options
2 import std/random 2 import std/random
3 3
4 import ../semiconginev2 4 import ../semiconginev2
5 5
6 var 6 proc test_01_triangle(nFrames: int, swapchain: var Swapchain) =
7 mainRenderpass: VkRenderPass
8 swapchain: Swapchain
9
10 proc test_01_triangle(nFrames: int, renderPass: VkRenderPass, samples = VK_SAMPLE_COUNT_1_BIT) =
11 var renderdata = InitRenderData() 7 var renderdata = InitRenderData()
12 8
13 type 9 type
14 TrianglShader = object 10 TrianglShader = object
15 position {.VertexAttribute.}: Vec3f 11 position {.VertexAttribute.}: Vec3f
31 ) 27 )
32 AssignBuffers(renderdata, mesh) 28 AssignBuffers(renderdata, mesh)
33 renderdata.FlushAllMemory() 29 renderdata.FlushAllMemory()
34 30
35 var 31 var
36 pipeline = CreatePipeline[TrianglShader](renderPass = renderPass, samples = samples) 32 pipeline = CreatePipeline[TrianglShader](renderPass = swapchain.renderPass)
37 33
38 var c = 0 34 var c = 0
39 while UpdateInputs() and c < nFrames: 35 while UpdateInputs() and c < nFrames:
40 WithNextFrame(swapchain, framebuffer, commandbuffer): 36 WithNextFrame(swapchain, framebuffer, commandbuffer):
41 WithRenderPass(renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): 37 WithRenderPass(swapchain.renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)):
42 WithPipeline(commandbuffer, pipeline): 38 WithPipeline(commandbuffer, pipeline):
43 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh) 39 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh)
44 inc c 40 inc c
45 41
46 # cleanup 42 # cleanup
47 checkVkResult vkDeviceWaitIdle(vulkan.device) 43 checkVkResult vkDeviceWaitIdle(vulkan.device)
48 DestroyPipeline(pipeline) 44 DestroyPipeline(pipeline)
49 DestroyRenderData(renderdata) 45 DestroyRenderData(renderdata)
50 46
51 47
52 proc test_02_triangle_quad_instanced(nFrames: int, renderPass: VkRenderPass, samples = VK_SAMPLE_COUNT_1_BIT) = 48 proc test_02_triangle_quad_instanced(nFrames: int, swapchain: var Swapchain) =
53 var renderdata = InitRenderData() 49 var renderdata = InitRenderData()
54 50
55 type 51 type
56 SomeShader = object 52 SomeShader = object
57 position {.VertexAttribute.}: Vec3f 53 position {.VertexAttribute.}: Vec3f
99 AssignBuffers(renderdata, quad) 95 AssignBuffers(renderdata, quad)
100 AssignBuffers(renderdata, instancesA) 96 AssignBuffers(renderdata, instancesA)
101 AssignBuffers(renderdata, instancesB) 97 AssignBuffers(renderdata, instancesB)
102 renderdata.FlushAllMemory() 98 renderdata.FlushAllMemory()
103 99
104 var pipeline = CreatePipeline[SomeShader](renderPass = renderPass, samples = samples) 100 var pipeline = CreatePipeline[SomeShader](renderPass = swapchain.renderPass)
105 101
106 var c = 0 102 var c = 0
107 while UpdateInputs() and c < nFrames: 103 while UpdateInputs() and c < nFrames:
108 WithNextFrame(swapchain, framebuffer, commandbuffer): 104 WithNextFrame(swapchain, framebuffer, commandbuffer):
109 WithRenderPass(renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): 105 WithRenderPass(swapchain.renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)):
110 WithPipeline(commandbuffer, pipeline): 106 WithPipeline(commandbuffer, pipeline):
111 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad, instances = instancesA) 107 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad, instances = instancesA)
112 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad, instances = instancesB) 108 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad, instances = instancesB)
113 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = tri, instances = instancesA) 109 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = tri, instances = instancesA)
114 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = tri, instances = instancesB) 110 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = tri, instances = instancesB)
117 # cleanup 113 # cleanup
118 checkVkResult vkDeviceWaitIdle(vulkan.device) 114 checkVkResult vkDeviceWaitIdle(vulkan.device)
119 DestroyPipeline(pipeline) 115 DestroyPipeline(pipeline)
120 DestroyRenderData(renderdata) 116 DestroyRenderData(renderdata)
121 117
122 proc test_03_simple_descriptorset(nFrames: int, renderPass: VkRenderPass, samples = VK_SAMPLE_COUNT_1_BIT) = 118 proc test_03_simple_descriptorset(nFrames: int, swapchain: var Swapchain) =
123 var renderdata = InitRenderData() 119 var renderdata = InitRenderData()
124 120
125 type 121 type
126 Material = object 122 Material = object
127 baseColor: Vec3f 123 baseColor: Vec3f
176 AssignBuffers(renderdata, uniforms2) 172 AssignBuffers(renderdata, uniforms2)
177 UploadImages(renderdata, uniforms1) 173 UploadImages(renderdata, uniforms1)
178 UploadImages(renderdata, uniforms2) 174 UploadImages(renderdata, uniforms2)
179 renderdata.FlushAllMemory() 175 renderdata.FlushAllMemory()
180 176
181 var pipeline = CreatePipeline[QuadShader](renderPass = renderPass, samples = samples) 177 var pipeline = CreatePipeline[QuadShader](renderPass = swapchain.renderPass)
182 178
183 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], uniforms1) 179 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], uniforms1)
184 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], uniforms2) 180 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], uniforms2)
185 181
186 var c = 0 182 var c = 0
187 while UpdateInputs() and c < nFrames: 183 while UpdateInputs() and c < nFrames:
188 WithNextFrame(swapchain, framebuffer, commandbuffer): 184 WithNextFrame(swapchain, framebuffer, commandbuffer):
189 WithRenderPass(renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): 185 WithRenderPass(swapchain.renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)):
190 WithPipeline(commandbuffer, pipeline): 186 WithPipeline(commandbuffer, pipeline):
191 WithBind(commandbuffer, (uniforms1, ), pipeline, swapchain.currentFiF): 187 WithBind(commandbuffer, (uniforms1, ), pipeline, swapchain.currentFiF):
192 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 188 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
193 WithBind(commandbuffer, (uniforms2, ), pipeline, swapchain.currentFiF): 189 WithBind(commandbuffer, (uniforms2, ), pipeline, swapchain.currentFiF):
194 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 190 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
197 # cleanup 193 # cleanup
198 checkVkResult vkDeviceWaitIdle(vulkan.device) 194 checkVkResult vkDeviceWaitIdle(vulkan.device)
199 DestroyPipeline(pipeline) 195 DestroyPipeline(pipeline)
200 DestroyRenderData(renderdata) 196 DestroyRenderData(renderdata)
201 197
202 proc test_04_multiple_descriptorsets(nFrames: int, renderPass: VkRenderPass, samples = VK_SAMPLE_COUNT_1_BIT) = 198 proc test_04_multiple_descriptorsets(nFrames: int, swapchain: var Swapchain) =
203 var renderdata = InitRenderData() 199 var renderdata = InitRenderData()
204 200
205 type 201 type
206 RenderSettings = object 202 RenderSettings = object
207 brigthness: float32 203 brigthness: float32
284 AssignBuffers(renderdata, otherset1) 280 AssignBuffers(renderdata, otherset1)
285 AssignBuffers(renderdata, otherset2) 281 AssignBuffers(renderdata, otherset2)
286 UploadImages(renderdata, mainset) 282 UploadImages(renderdata, mainset)
287 renderdata.FlushAllMemory() 283 renderdata.FlushAllMemory()
288 284
289 var pipeline = CreatePipeline[QuadShader](renderPass = renderPass, samples = samples) 285 var pipeline = CreatePipeline[QuadShader](renderPass = swapchain.renderPass)
290 286
291 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], constset) 287 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], constset)
292 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[1], mainset) 288 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[1], mainset)
293 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset1) 289 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset1)
294 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset2) 290 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset2)
295 291
296 var c = 0 292 var c = 0
297 while UpdateInputs() and c < nFrames: 293 while UpdateInputs() and c < nFrames:
298 TimeAndLog: 294 TimeAndLog:
299 WithNextFrame(swapchain, framebuffer, commandbuffer): 295 WithNextFrame(swapchain, framebuffer, commandbuffer):
300 WithRenderPass(renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): 296 WithRenderPass(swapchain.renderPass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)):
301 WithPipeline(commandbuffer, pipeline): 297 WithPipeline(commandbuffer, pipeline):
302 WithBind(commandbuffer, (constset, mainset, otherset1), pipeline, swapchain.currentFiF): 298 WithBind(commandbuffer, (constset, mainset, otherset1), pipeline, swapchain.currentFiF):
303 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 299 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
304 WithBind(commandbuffer, (constset, mainset, otherset2), pipeline, swapchain.currentFiF): 300 WithBind(commandbuffer, (constset, mainset, otherset2), pipeline, swapchain.currentFiF):
305 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 301 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
313 # cleanup 309 # cleanup
314 checkVkResult vkDeviceWaitIdle(vulkan.device) 310 checkVkResult vkDeviceWaitIdle(vulkan.device)
315 DestroyPipeline(pipeline) 311 DestroyPipeline(pipeline)
316 DestroyRenderData(renderdata) 312 DestroyRenderData(renderdata)
317 313
318 proc test_05_triangle_2pass(nFrames: int, samples = VK_SAMPLE_COUNT_1_BIT) = 314 proc test_05_triangle_2pass(nFrames: int) =
319 var 315 var
320 (offscreenRP, presentRP) = CreateIndirectPresentationRenderPass() 316 (offscreenRP, presentRP) = CreateIndirectPresentationRenderPass(depthBuffer = true, samples = VK_SAMPLE_COUNT_4_BIT)
321 swapchain = InitSwapchain(renderpass = presentRP).get() 317 swapchain = InitSwapchain(renderpass = presentRP).get()
322 318
323 var renderdata = InitRenderData() 319 var renderdata = InitRenderData()
324 320
325 type 321 type
374 var uniforms1 = asDescriptorSet( 370 var uniforms1 = asDescriptorSet(
375 Uniforms( 371 Uniforms(
376 frameTexture: Image[TVec4[uint8]](width: swapchain.width, height: swapchain.height, isRenderTarget: true), 372 frameTexture: Image[TVec4[uint8]](width: swapchain.width, height: swapchain.height, isRenderTarget: true),
377 ) 373 )
378 ) 374 )
379 var uniforms2 = asDescriptorSet(
380 Uniforms(
381 frameTexture: Image[TVec4[uint8]](width: swapchain.width, height: swapchain.height, isRenderTarget: true),
382 )
383 )
384 AssignBuffers(renderdata, mesh) 375 AssignBuffers(renderdata, mesh)
385 AssignBuffers(renderdata, quad) 376 AssignBuffers(renderdata, quad)
386 UploadImages(renderdata, uniforms1) 377 UploadImages(renderdata, uniforms1)
387 UploadImages(renderdata, uniforms2)
388 renderdata.FlushAllMemory() 378 renderdata.FlushAllMemory()
389 379
390 var 380 var
391 drawPipeline = CreatePipeline[TriangleShader](renderPass = offscreenRP, samples = samples) 381 drawPipeline = CreatePipeline[TriangleShader](renderPass = offscreenRP)
392 presentPipeline = CreatePipeline[PresentShader](renderPass = presentRP, samples = samples) 382 presentPipeline = CreatePipeline[PresentShader](renderPass = presentRP)
393 383
394 InitDescriptorSet(renderdata, presentPipeline.descriptorSetLayouts[0], uniforms1) 384 InitDescriptorSet(renderdata, presentPipeline.descriptorSetLayouts[0], uniforms1)
395 InitDescriptorSet(renderdata, presentPipeline.descriptorSetLayouts[0], uniforms2) 385
396 386 # create depth buffer images (will not use the one in the swapchain
397 var offscreenFB = svkCreateFramebuffer(offscreenRP, swapchain.width, swapchain.height, [uniforms1.data.frameTexture.imageview]) 387 var
388 depthImage: VkImage
389 depthImageView: VkImageView
390 depthMemory: VkDeviceMemory
391 if offscreenRP.depthBuffer:
392 depthImage = svkCreate2DImage(
393 width = swapchain.width,
394 height = swapchain.height,
395 format = DEPTH_FORMAT,
396 usage = [VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT],
397 samples = offscreenRP.samples,
398 )
399 let requirements = svkGetImageMemoryRequirements(depthImage)
400 depthMemory = svkAllocateMemory(
401 requirements.size,
402 BestMemory(mappable = false, filter = requirements.memoryTypes)
403 )
404 checkVkResult vkBindImageMemory(
405 vulkan.device,
406 depthImage,
407 depthMemory,
408 0,
409 )
410 depthImageView = svkCreate2DImageView(
411 image = depthImage,
412 format = DEPTH_FORMAT,
413 aspect = VK_IMAGE_ASPECT_DEPTH_BIT
414 )
415
416 # create msaa images (will not use the one in the swapchain
417 var
418 msaaImage: VkImage
419 msaaImageView: VkImageView
420 msaaMemory: VkDeviceMemory
421 if offscreenRP.samples != VK_SAMPLE_COUNT_1_BIT:
422 msaaImage = svkCreate2DImage(
423 width = swapchain.width,
424 height = swapchain.height,
425 format = SURFACE_FORMAT,
426 usage = [VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT],
427 samples = offscreenRP.samples,
428 )
429 let requirements = svkGetImageMemoryRequirements(msaaImage)
430 msaaMemory = svkAllocateMemory(
431 requirements.size,
432 BestMemory(mappable = false, filter = requirements.memoryTypes)
433 )
434 checkVkResult vkBindImageMemory(
435 vulkan.device,
436 msaaImage,
437 msaaMemory,
438 0,
439 )
440 msaaImageView = svkCreate2DImageView(image = msaaImage, format = SURFACE_FORMAT)
441
442 var attachments: seq[VkImageView]
443 if offscreenRP.samples == VK_SAMPLE_COUNT_1_BIT:
444 if offscreenRP.depthBuffer:
445 attachments = @[uniforms1.data.frameTexture.imageview, depthImageView]
446 else:
447 attachments = @[uniforms1.data.frameTexture.imageview]
448 else:
449 if offscreenRP.depthBuffer:
450 attachments = @[msaaImageView, depthImageView, uniforms1.data.frameTexture.imageview]
451 else:
452 attachments = @[msaaImageView, uniforms1.data.frameTexture.imageview]
453 echo attachments
454 var offscreenFB = svkCreateFramebuffer(
455 offscreenRP.vk,
456 swapchain.width,
457 swapchain.height,
458 attachments
459 )
398 460
399 var c = 0 461 var c = 0
400 while UpdateInputs() and c < nFrames: 462 while UpdateInputs() and c < nFrames:
401 463
402 TimeAndLog: 464 TimeAndLog:
415 # cleanup 477 # cleanup
416 checkVkResult vkDeviceWaitIdle(vulkan.device) 478 checkVkResult vkDeviceWaitIdle(vulkan.device)
417 DestroyPipeline(presentPipeline) 479 DestroyPipeline(presentPipeline)
418 DestroyPipeline(drawPipeline) 480 DestroyPipeline(drawPipeline)
419 DestroyRenderData(renderdata) 481 DestroyRenderData(renderdata)
420 vkDestroyRenderPass(vulkan.device, offscreenRP, nil) 482 if depthImage.Valid:
421 vkDestroyRenderPass(vulkan.device, presentRP, nil) 483 vkDestroyImageView(vulkan.device, depthImageView, nil)
484 vkDestroyImage(vulkan.device, depthImage, nil)
485 vkFreeMemory(vulkan.device, depthMemory, nil)
486 if msaaImage.Valid:
487 vkDestroyImageView(vulkan.device, msaaImageView, nil)
488 vkDestroyImage(vulkan.device, msaaImage, nil)
489 vkFreeMemory(vulkan.device, msaaMemory, nil)
490 vkDestroyRenderPass(vulkan.device, offscreenRP.vk, nil)
491 vkDestroyRenderPass(vulkan.device, presentRP.vk, nil)
422 vkDestroyFramebuffer(vulkan.device, offscreenFB, nil) 492 vkDestroyFramebuffer(vulkan.device, offscreenFB, nil)
423 DestroySwapchain(swapchain) 493 DestroySwapchain(swapchain)
424 494
425 when isMainModule: 495 when isMainModule:
426 var nFrames = 2000 496 var nFrames = 1000
427 InitVulkan() 497 InitVulkan()
428 498
499 var mainRenderpass: RenderPass
500 var renderPasses = [
501 (depthBuffer: false, samples: VK_SAMPLE_COUNT_1_BIT),
502 (depthBuffer: false, samples: VK_SAMPLE_COUNT_4_BIT),
503 (depthBuffer: true, samples: VK_SAMPLE_COUNT_1_BIT),
504 (depthBuffer: true, samples: VK_SAMPLE_COUNT_4_BIT),
505 ]
429 506
430 # test normal 507 # test normal
431 block: 508 if false:
432 mainRenderpass = CreateDirectPresentationRenderPass() 509 for i, (depthBuffer, samples) in renderPasses:
433 swapchain = InitSwapchain(renderpass = mainRenderpass).get() 510 var renderpass = CreateDirectPresentationRenderPass(depthBuffer = depthBuffer, samples = samples)
434 511 var swapchain = InitSwapchain(renderpass = renderpass).get()
435 # tests a simple triangle with minimalistic shader and vertex format 512
436 test_01_triangle(nFrames, renderPass = mainRenderpass) 513 # tests a simple triangle with minimalistic shader and vertex format
437 514 test_01_triangle(nFrames, swapchain)
438 # tests instanced triangles and quads, mixing meshes and instances 515
439 test_02_triangle_quad_instanced(nFrames, renderPass = mainRenderpass) 516 # tests instanced triangles and quads, mixing meshes and instances
440 517 test_02_triangle_quad_instanced(nFrames, swapchain)
441 # teste descriptor sets 518
442 test_03_simple_descriptorset(nFrames, renderPass = mainRenderpass) 519 # teste descriptor sets
443 520 test_03_simple_descriptorset(nFrames, swapchain)
444 # tests multiple descriptor sets and arrays 521
445 test_04_multiple_descriptorsets(nFrames, renderPass = mainRenderpass) 522 # tests multiple descriptor sets and arrays
446 523 test_04_multiple_descriptorsets(nFrames, swapchain)
447 checkVkResult vkDeviceWaitIdle(vulkan.device) 524
448 vkDestroyRenderPass(vulkan.device, mainRenderpass, nil) 525 checkVkResult vkDeviceWaitIdle(vulkan.device)
449 DestroySwapchain(swapchain) 526 vkDestroyRenderPass(vulkan.device, renderpass.vk, nil)
450 527 DestroySwapchain(swapchain)
451 # test MSAA
452 block:
453 mainRenderpass = CreateDirectPresentationRenderPass(samples = VK_SAMPLE_COUNT_4_BIT)
454 swapchain = InitSwapchain(renderpass = mainRenderpass, samples = VK_SAMPLE_COUNT_4_BIT).get()
455
456 test_01_triangle(nFrames, renderPass = mainRenderpass, VK_SAMPLE_COUNT_4_BIT)
457
458 checkVkResult vkDeviceWaitIdle(vulkan.device)
459 vkDestroyRenderPass(vulkan.device, mainRenderpass, nil)
460 DestroySwapchain(swapchain)
461 528
462 # test multiple render passes 529 # test multiple render passes
463 block: 530 block:
464 test_05_triangle_2pass(999999999) 531 test_05_triangle_2pass(nFrames)
465 532
466 DestroyVulkan() 533 DestroyVulkan()