comparison tests/test_rendering.nim @ 1322:4a1c2b1128bc

did: improve handling of descriptor sets
author sam <sam@basx.dev>
date Thu, 15 Aug 2024 18:30:00 +0700
parents 6d0162bfe48a
children df3c075e5dea
comparison
equal deleted inserted replaced
1321:385dbd68a947 1322:4a1c2b1128bc
15 PushConstant = object 15 PushConstant = object
16 scale: float32 16 scale: float32
17 Shader = object 17 Shader = object
18 position {.VertexAttribute.}: Vec3f 18 position {.VertexAttribute.}: Vec3f
19 color {.VertexAttribute.}: Vec3f 19 color {.VertexAttribute.}: Vec3f
20 pushConstant {.PushConstantAttribute.}: PushConstant 20 pushConstant {.PushConstant.}: PushConstant
21 fragmentColor {.Pass.}: Vec3f 21 fragmentColor {.Pass.}: Vec3f
22 outColor {.ShaderOutput.}: Vec4f 22 outColor {.ShaderOutput.}: Vec4f
23 # code 23 # code
24 vertexCode: string = """void main() { 24 vertexCode: string = """void main() {
25 fragmentColor = color; 25 fragmentColor = color;
142 QuadShader = object 142 QuadShader = object
143 position {.VertexAttribute.}: Vec3f 143 position {.VertexAttribute.}: Vec3f
144 fragmentColor {.Pass.}: Vec3f 144 fragmentColor {.Pass.}: Vec3f
145 uv {.Pass.}: Vec2f 145 uv {.Pass.}: Vec2f
146 outColor {.ShaderOutput.}: Vec4f 146 outColor {.ShaderOutput.}: Vec4f
147 descriptorSets {.DescriptorSets.}: (Uniforms, ) 147 descriptorSets {.DescriptorSet: 0.}: Uniforms
148 # code 148 # code
149 vertexCode: string = """void main() { 149 vertexCode: string = """void main() {
150 fragmentColor = material.baseColor; 150 fragmentColor = material.baseColor;
151 gl_Position = vec4(position, 1); 151 gl_Position = vec4(position, 1);
152 gl_Position.x += ((material.baseColor.b - 0.5) * 2) - 0.5; 152 gl_Position.x += ((material.baseColor.b - 0.5) * 2) - 0.5;
165 var 165 var
166 quad = QuadMesh( 166 quad = QuadMesh(
167 position: asGPUArray([vec3(-0.5, -0.5, 0), vec3(-0.5, 0.5, 0), vec3(0.5, 0.5, 0), vec3(0.5, -0.5, 0)], VertexBuffer), 167 position: asGPUArray([vec3(-0.5, -0.5, 0), vec3(-0.5, 0.5, 0), vec3(0.5, 0.5, 0), vec3(0.5, -0.5, 0)], VertexBuffer),
168 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer), 168 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer),
169 ) 169 )
170 uniforms1 = asDescriptorSet( 170 uniforms1 = asDescriptorSetData(
171 Uniforms( 171 Uniforms(
172 material: asGPUValue(Material(baseColor: vec3(1, 1, 1)), UniformBuffer), 172 material: asGPUValue(Material(baseColor: vec3(1, 1, 1)), UniformBuffer),
173 texture1: Image[BGRA](width: 3, height: 3, data: @[R, G, B, G, B, R, B, R, G], minInterpolation: VK_FILTER_NEAREST, magInterpolation: VK_FILTER_NEAREST), 173 texture1: Image[BGRA](width: 3, height: 3, data: @[R, G, B, G, B, R, B, R, G], minInterpolation: VK_FILTER_NEAREST, magInterpolation: VK_FILTER_NEAREST),
174 ) 174 )
175 ) 175 )
176 uniforms2 = asDescriptorSet( 176 uniforms2 = asDescriptorSetData(
177 Uniforms( 177 Uniforms(
178 material: asGPUValue(Material(baseColor: vec3(0.5, 0.5, 0.5)), UniformBuffer), 178 material: asGPUValue(Material(baseColor: vec3(0.5, 0.5, 0.5)), UniformBuffer),
179 texture1: Image[BGRA](width: 2, height: 2, data: @[R, G, B, W]), 179 texture1: Image[BGRA](width: 2, height: 2, data: @[R, G, B, W]),
180 ) 180 )
181 ) 181 )
199 199
200 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): 200 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)):
201 201
202 withPipeline(commandbuffer, pipeline): 202 withPipeline(commandbuffer, pipeline):
203 203
204 withBind(commandbuffer, (uniforms1, ), pipeline): 204 bindDescriptorSet(commandbuffer, uniforms1, 0, pipeline)
205 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 205 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
206 206
207 withBind(commandbuffer, (uniforms2, ), pipeline): 207 bindDescriptorSet(commandbuffer, uniforms2, 0, pipeline)
208 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 208 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
209 209
210 # cleanup 210 # cleanup
211 checkVkResult vkDeviceWaitIdle(vulkan.device) 211 checkVkResult vkDeviceWaitIdle(vulkan.device)
212 destroyPipeline(pipeline) 212 destroyPipeline(pipeline)
213 destroyRenderData(renderdata) 213 destroyRenderData(renderdata)
238 QuadShader = object 238 QuadShader = object
239 position {.VertexAttribute.}: Vec3f 239 position {.VertexAttribute.}: Vec3f
240 fragmentColor {.Pass.}: Vec3f 240 fragmentColor {.Pass.}: Vec3f
241 uv {.Pass.}: Vec2f 241 uv {.Pass.}: Vec2f
242 outColor {.ShaderOutput.}: Vec4f 242 outColor {.ShaderOutput.}: Vec4f
243 descriptorSets {.DescriptorSets.}: (ConstSet, MainSet, OtherSet) 243 descriptorSets0 {.DescriptorSet: 0.}: ConstSet
244 descriptorSets1 {.DescriptorSet: 1.}: MainSet
245 descriptorSets2 {.DescriptorSet: 2.}: OtherSet
244 # code 246 # code
245 vertexCode: string = """void main() { 247 vertexCode: string = """void main() {
246 fragmentColor = material[objectSettings.materialIndex].baseColor * renderSettings.brigthness; 248 fragmentColor = material[objectSettings.materialIndex].baseColor * renderSettings.brigthness;
247 gl_Position = vec4(position * objectSettings.scale, 1); 249 gl_Position = vec4(position * objectSettings.scale, 1);
248 gl_Position.xy += constants.offset.xy; 250 gl_Position.xy += constants.offset.xy;
258 260
259 var quad = QuadMesh( 261 var quad = QuadMesh(
260 position: asGPUArray([vec3(-0.5, -0.5), vec3(-0.5, 0.5), vec3(0.5, 0.5), vec3(0.5, -0.5)], VertexBuffer), 262 position: asGPUArray([vec3(-0.5, -0.5), vec3(-0.5, 0.5), vec3(0.5, 0.5), vec3(0.5, -0.5)], VertexBuffer),
261 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer), 263 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer),
262 ) 264 )
263 var constset = asDescriptorSet( 265 var constset = asDescriptorSetData(
264 ConstSet( 266 ConstSet(
265 constants: asGPUValue(Constants(offset: vec2(-0.3, 0.2)), UniformBuffer), 267 constants: asGPUValue(Constants(offset: vec2(-0.3, 0.2)), UniformBuffer),
266 ) 268 )
267 ) 269 )
268 let G = Gray([50'u8]) 270 let G = Gray([50'u8])
269 let W = Gray([255'u8]) 271 let W = Gray([255'u8])
270 var mainset = asDescriptorSet( 272 var mainset = asDescriptorSetData(
271 MainSet( 273 MainSet(
272 renderSettings: asGPUValue(RenderSettings(brigthness: 0), UniformBufferMapped), 274 renderSettings: asGPUValue(RenderSettings(brigthness: 0), UniformBufferMapped),
273 material: [ 275 material: [
274 asGPUValue(Material(baseColor: vec3(1, 1, 0)), UniformBuffer), 276 asGPUValue(Material(baseColor: vec3(1, 1, 0)), UniformBuffer),
275 asGPUValue(Material(baseColor: vec3(1, 0, 1)), UniformBuffer), 277 asGPUValue(Material(baseColor: vec3(1, 0, 1)), UniformBuffer),
278 Image[Gray](width: 2, height: 2, data: @[W, G, G, W], minInterpolation: VK_FILTER_NEAREST, magInterpolation: VK_FILTER_NEAREST), 280 Image[Gray](width: 2, height: 2, data: @[W, G, G, W], minInterpolation: VK_FILTER_NEAREST, magInterpolation: VK_FILTER_NEAREST),
279 Image[Gray](width: 3, height: 3, data: @[W, G, W, G, W, G, W, G, W], minInterpolation: VK_FILTER_NEAREST, magInterpolation: VK_FILTER_NEAREST), 281 Image[Gray](width: 3, height: 3, data: @[W, G, W, G, W, G, W, G, W], minInterpolation: VK_FILTER_NEAREST, magInterpolation: VK_FILTER_NEAREST),
280 ], 282 ],
281 ), 283 ),
282 ) 284 )
283 var otherset1 = asDescriptorSet( 285 var otherset1 = asDescriptorSetData(
284 OtherSet( 286 OtherSet(
285 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 0), UniformBufferMapped), 287 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 0), UniformBufferMapped),
286 ) 288 )
287 ) 289 )
288 var otherset2 = asDescriptorSet( 290 var otherset2 = asDescriptorSetData(
289 OtherSet( 291 OtherSet(
290 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 1), UniformBufferMapped), 292 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 1), UniformBufferMapped),
291 ) 293 )
292 ) 294 )
293 295
308 310
309 var start = getMonoTime() 311 var start = getMonoTime()
310 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time: 312 while ((getMonoTime() - start).inMilliseconds().int / 1000) < time:
311 313
312 withNextFrame(framebuffer, commandbuffer): 314 withNextFrame(framebuffer, commandbuffer):
315 bindDescriptorSet(commandbuffer, constset, 0, pipeline)
316 bindDescriptorSet(commandbuffer, mainset, 1, pipeline)
313 317
314 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): 318 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)):
315 319
316 withPipeline(commandbuffer, pipeline): 320 withPipeline(commandbuffer, pipeline):
317 321
318 withBind(commandbuffer, (constset, mainset, otherset1), pipeline): 322 bindDescriptorSet(commandbuffer, otherset1, 2, pipeline)
319 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 323 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
320 324
321 withBind(commandbuffer, (constset, mainset, otherset2), pipeline): 325 bindDescriptorSet(commandbuffer, otherset2, 2, pipeline)
322 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) 326 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad)
323 327
324 mainset.data.renderSettings.data.brigthness = ((getMonoTime() - start).inMilliseconds().int / 1000) / time 328 mainset.data.renderSettings.data.brigthness = ((getMonoTime() - start).inMilliseconds().int / 1000) / time
325 otherset1.data.objectSettings.data.scale = 0.5 + ((getMonoTime() - start).inMilliseconds().int / 1000) / time 329 otherset1.data.objectSettings.data.scale = 0.5 + ((getMonoTime() - start).inMilliseconds().int / 1000) / time
326 updateGPUBuffer(mainset.data.renderSettings) 330 updateGPUBuffer(mainset.data.renderSettings)
327 updateGPUBuffer(otherset1.data.objectSettings) 331 updateGPUBuffer(otherset1.data.objectSettings)
342 CubeShader = object 346 CubeShader = object
343 position {.VertexAttribute.}: Vec3f 347 position {.VertexAttribute.}: Vec3f
344 color {.VertexAttribute.}: Vec4f 348 color {.VertexAttribute.}: Vec4f
345 fragmentColor {.Pass.}: Vec4f 349 fragmentColor {.Pass.}: Vec4f
346 outColor {.ShaderOutput.}: Vec4f 350 outColor {.ShaderOutput.}: Vec4f
347 descriptorSets {.DescriptorSets.}: (Uniforms, ) 351 descriptorSets {.DescriptorSet: 0.}: Uniforms
348 # code 352 # code
349 vertexCode = """void main() { 353 vertexCode = """void main() {
350 fragmentColor = color; 354 fragmentColor = color;
351 gl_Position = vec4(position, 1) * data.mvp; 355 gl_Position = vec4(position, 1) * data.mvp;
352 }""" 356 }"""
415 color: asGPUArray(newSeqWith(6, vec4(0.1, 0.1, 0.1, 1)), VertexBuffer), 419 color: asGPUArray(newSeqWith(6, vec4(0.1, 0.1, 0.1, 1)), VertexBuffer),
416 normals: asGPUArray(newSeqWith(6, Y), VertexBuffer), 420 normals: asGPUArray(newSeqWith(6, Y), VertexBuffer),
417 ) 421 )
418 assignBuffers(renderdata, floor) 422 assignBuffers(renderdata, floor)
419 423
420 var uniforms1 = asDescriptorSet( 424 var uniforms1 = asDescriptorSetData(
421 Uniforms( 425 Uniforms(
422 data: asGPUValue(UniformData(mvp: Unit4), UniformBufferMapped) 426 data: asGPUValue(UniformData(mvp: Unit4), UniformBufferMapped)
423 ) 427 )
424 ) 428 )
425 assignBuffers(renderdata, uniforms1) 429 assignBuffers(renderdata, uniforms1)
447 withNextFrame(framebuffer, commandbuffer): 451 withNextFrame(framebuffer, commandbuffer):
448 452
449 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): 453 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)):
450 withPipeline(commandbuffer, pipeline): 454 withPipeline(commandbuffer, pipeline):
451 455
452 withBind(commandbuffer, (uniforms1, ), pipeline): 456 bindDescriptorSet(commandbuffer, uniforms1, 0, pipeline)
453 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh) 457 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh)
454 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = floor) 458 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = floor)
455 459
456 let tEndLoop = getMonoTime() - tStart 460 let tEndLoop = getMonoTime() - tStart
457 let looptime = tEndLoop - tStartLoop 461 let looptime = tEndLoop - tStartLoop
458 let waitTime = 16_666 - looptime.inMicroseconds 462 let waitTime = 16_666 - looptime.inMicroseconds
459 if waitTime > 0: 463 if waitTime > 0:
530 Shader = object 534 Shader = object
531 position {.VertexAttribute.}: Vec3f 535 position {.VertexAttribute.}: Vec3f
532 uv {.VertexAttribute.}: Vec2f 536 uv {.VertexAttribute.}: Vec2f
533 fragmentUv {.Pass.}: Vec2f 537 fragmentUv {.Pass.}: Vec2f
534 outColor {.ShaderOutput.}: Vec4f 538 outColor {.ShaderOutput.}: Vec4f
535 descriptorSets {.DescriptorSets.}: (Uniforms, ) 539 descriptorSets {.DescriptorSet: 0.}: Uniforms
536 # code 540 # code
537 vertexCode: string = """ 541 vertexCode: string = """
538 void main() { 542 void main() {
539 fragmentUv = uv; 543 fragmentUv = uv;
540 gl_Position = vec4(position, 1); 544 gl_Position = vec4(position, 1);
558 ) 562 )
559 assignBuffers(renderdata, mesh) 563 assignBuffers(renderdata, mesh)
560 renderdata.flushAllMemory() 564 renderdata.flushAllMemory()
561 565
562 var pipeline = createPipeline[Shader](renderPass = vulkan.swapchain.renderPass) 566 var pipeline = createPipeline[Shader](renderPass = vulkan.swapchain.renderPass)
563 var uniforms1 = asDescriptorSet( 567 var uniforms1 = asDescriptorSetData(
564 Uniforms( 568 Uniforms(
565 texture1: loadImage[BGRA]("art.png"), 569 texture1: loadImage[BGRA]("art.png"),
566 ) 570 )
567 ) 571 )
568 uploadImages(renderdata, uniforms1) 572 uploadImages(renderdata, uniforms1)
575 579
576 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): 580 withRenderPass(vulkan.swapchain.renderPass, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)):
577 581
578 withPipeline(commandbuffer, pipeline): 582 withPipeline(commandbuffer, pipeline):
579 583
580 withBind(commandbuffer, (uniforms1, ), pipeline): 584 bindDescriptorSet(commandbuffer, uniforms1, 0, pipeline)
581 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh) 585 render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh)
582 586
583 # cleanup 587 # cleanup
584 checkVkResult vkDeviceWaitIdle(vulkan.device) 588 checkVkResult vkDeviceWaitIdle(vulkan.device)
585 destroyPipeline(pipeline) 589 destroyPipeline(pipeline)
586 destroyRenderData(renderdata) 590 destroyRenderData(renderdata)
608 outColor = vec4(fragmentColor, 1);}""" 612 outColor = vec4(fragmentColor, 1);}"""
609 PresentShader = object 613 PresentShader = object
610 position {.VertexAttribute.}: Vec2f 614 position {.VertexAttribute.}: Vec2f
611 uv {.Pass.}: Vec2f 615 uv {.Pass.}: Vec2f
612 outColor {.ShaderOutput.}: Vec4f 616 outColor {.ShaderOutput.}: Vec4f
613 descriptorSets {.DescriptorSets.}: (Uniforms, ) 617 descriptorSets {.DescriptorSet: 0.}: Uniforms
614 # code 618 # code
615 vertexCode: string = """void main() { 619 vertexCode: string = """void main() {
616 uv = ((position + 1) * 0.5) * vec2(1, -1); 620 uv = ((position + 1) * 0.5) * vec2(1, -1);
617 gl_Position = vec4(position, 0, 1);}""" 621 gl_Position = vec4(position, 0, 1);}"""
618 fragmentCode: string = """void main() { 622 fragmentCode: string = """void main() {
639 ) 643 )
640 var quad = QuadMesh( 644 var quad = QuadMesh(
641 position: asGPUArray([vec2(-1, -1), vec2(-1, 1), vec2(1, 1), vec2(1, -1)], VertexBuffer), 645 position: asGPUArray([vec2(-1, -1), vec2(-1, 1), vec2(1, 1), vec2(1, -1)], VertexBuffer),
642 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer), 646 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer),
643 ) 647 )
644 var uniforms1 = asDescriptorSet( 648 var uniforms1 = asDescriptorSetData(
645 Uniforms( 649 Uniforms(
646 frameTexture: Image[BGRA](width: vulkan.swapchain.width, height: vulkan.swapchain.height, isRenderTarget: true), 650 frameTexture: Image[BGRA](width: vulkan.swapchain.width, height: vulkan.swapchain.height, isRenderTarget: true),
647 ) 651 )
648 ) 652 )
649 assignBuffers(renderdata, mesh) 653 assignBuffers(renderdata, mesh)
742 746
743 withRenderPass(presentRP, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)): 747 withRenderPass(presentRP, framebuffer, commandbuffer, vulkan.swapchain.width, vulkan.swapchain.height, vec4(0, 0, 0, 0)):
744 748
745 withPipeline(commandbuffer, presentPipeline): 749 withPipeline(commandbuffer, presentPipeline):
746 750
747 withBind(commandbuffer, (uniforms1, ), presentPipeline): 751 bindDescriptorSet(commandbuffer, uniforms1, 0, presentPipeline)
748 render(commandbuffer = commandbuffer, pipeline = presentPipeline, mesh = quad) 752 render(commandbuffer = commandbuffer, pipeline = presentPipeline, mesh = quad)
749 753
750 # cleanup 754 # cleanup
751 checkVkResult vkDeviceWaitIdle(vulkan.device) 755 checkVkResult vkDeviceWaitIdle(vulkan.device)
752 destroyPipeline(presentPipeline) 756 destroyPipeline(presentPipeline)
753 destroyPipeline(drawPipeline) 757 destroyPipeline(drawPipeline)