comparison tests/test_rendering.nim @ 1204:e2901100a596 compiletime-tests

add: tests, some fixes, some helpers
author sam <sam@basx.dev>
date Mon, 15 Jul 2024 23:51:17 +0700
parents 6360c8d17ce0
children f7530247a21f
comparison
equal deleted inserted replaced
1203:6360c8d17ce0 1204:e2901100a596
1 import std/options 1 import std/options
2 import std/random
3
2 import ../semicongine 4 import ../semicongine
3 5
4 var 6 var
5 mainRenderpass: VkRenderPass 7 mainRenderpass: VkRenderPass
6 swapchain: Swapchain 8 swapchain: Swapchain
7 9
8 proc test_01_gl_triangle() = 10 proc test_01_triangle(nFrames: int) =
9 var renderdata = InitRenderData() 11 var renderdata = InitRenderData()
10 12
11 type 13 type
12 TrianglShader = object 14 TrianglShader = object
13 position {.VertexAttribute.}: Vec3f 15 position {.VertexAttribute.}: Vec3f
21 fragmentCode: string = """void main() { 23 fragmentCode: string = """void main() {
22 outColor = vec4(fragmentColor, 1);}""" 24 outColor = vec4(fragmentColor, 1);}"""
23 TriangleMesh = object 25 TriangleMesh = object
24 position: GPUArray[Vec3f, VertexBuffer] 26 position: GPUArray[Vec3f, VertexBuffer]
25 color: GPUArray[Vec3f, VertexBuffer] 27 color: GPUArray[Vec3f, VertexBuffer]
26 Empty = object
27 var mesh = TriangleMesh( 28 var mesh = TriangleMesh(
28 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(-0.5, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer), 29 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(0, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer),
29 color: asGPUArray([NewVec3f(0, 0, 1), NewVec3f(0, 1, 0), NewVec3f(1, 0, 0)], VertexBuffer), 30 color: asGPUArray([NewVec3f(0, 0, 1), NewVec3f(0, 1, 0), NewVec3f(1, 0, 0)], VertexBuffer),
30 ) 31 )
32 AssignBuffers(renderdata, mesh)
33 renderdata.FlushAllMemory()
31 34
32 var 35 var
33 pipeline = CreatePipeline[TrianglShader](renderPass = mainRenderpass) 36 pipeline = CreatePipeline[TrianglShader](renderPass = mainRenderpass, samples = swapchain.samples)
34 a, b: Empty 37
35 38 var c = 0
36 while UpdateInputs(): 39 while UpdateInputs() and c < nFrames:
37 WithNextFrame(swapchain, framebuffer, commandbuffer): 40 WithNextFrame(swapchain, framebuffer, commandbuffer):
38 WithRenderPass(mainRenderpass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): 41 WithRenderPass(mainRenderpass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)):
39 WithPipeline(commandbuffer, pipeline): 42 WithPipeline(commandbuffer, pipeline):
40 # WithBind(commandBuffer, a, b, pipeline, swapchain.currentFiF.int): 43 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh)
41 Render( 44 inc c
42 commandbuffer = commandbuffer,
43 pipeline = pipeline,
44 globalSet = a,
45 materialSet = b,
46 mesh = mesh,
47 )
48 45
49 # cleanup 46 # cleanup
47 checkVkResult vkDeviceWaitIdle(vulkan.device)
50 DestroyPipeline(pipeline) 48 DestroyPipeline(pipeline)
51 DestroyRenderData(renderdata) 49 DestroyRenderData(renderdata)
52 50
53 51
52 proc test_02_triangle_quad_instanced(nFrames: int) =
53 var renderdata = InitRenderData()
54
55 type
56 SomeShader = object
57 position {.VertexAttribute.}: Vec3f
58 color {.VertexAttribute.}: Vec3f
59 pos {.InstanceAttribute.}: Vec3f
60 scale {.InstanceAttribute.}: float32
61 fragmentColor {.Pass.}: Vec3f
62 outColor {.ShaderOutput.}: Vec4f
63 # code
64 vertexCode: string = """void main() {
65 fragmentColor = color;
66 gl_Position = vec4((position * scale) + pos, 1);}"""
67 fragmentCode: string = """void main() {
68 outColor = vec4(fragmentColor, 1);}"""
69 TriangleMesh = object
70 position: GPUArray[Vec3f, VertexBuffer]
71 color: GPUArray[Vec3f, VertexBuffer]
72 QuadMesh = object
73 position: GPUArray[Vec3f, VertexBuffer]
74 color: GPUArray[Vec3f, VertexBuffer]
75 indices: GPUArray[uint16, IndexBuffer]
76 Instances = object
77 pos: GPUArray[Vec3f, VertexBuffer]
78 scale: GPUArray[float32, VertexBuffer]
79 var tri = TriangleMesh(
80 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(0, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer),
81 color: asGPUArray([NewVec3f(0, 0, 1), NewVec3f(0, 1, 0), NewVec3f(1, 0, 0)], VertexBuffer),
82 )
83 var quad = QuadMesh(
84 position: asGPUArray([NewVec3f(-0.3, -0.3), NewVec3f(-0.3, 0.3), NewVec3f(0.3, 0.3), NewVec3f(0.3, -0.3)], VertexBuffer),
85 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer),
86 color: asGPUArray([NewVec3f(1, 1, 1), NewVec3f(1, 1, 1), NewVec3f(1, 1, 1), NewVec3f(1, 1, 1)], VertexBuffer),
87 )
88
89 var instancesA: Instances
90 for n in 1..100:
91 instancesA.pos.data.add NewVec3f(rand(-0.8'f32 .. 0.8'f32), rand(-0.8'f32 .. 0'f32))
92 instancesA.scale.data.add rand(0.3'f32 .. 0.4'f32)
93 var instancesB: Instances
94 for n in 1..100:
95 instancesB.pos.data.add NewVec3f(rand(-0.8'f32 .. 0.8'f32), rand(0'f32 .. 0.8'f32))
96 instancesB.scale.data.add rand(0.1'f32 .. 0.2'f32)
97
98 AssignBuffers(renderdata, tri)
99 AssignBuffers(renderdata, quad)
100 AssignBuffers(renderdata, instancesA)
101 AssignBuffers(renderdata, instancesB)
102 renderdata.FlushAllMemory()
103
104 var pipeline = CreatePipeline[SomeShader](renderPass = mainRenderpass, samples = swapchain.samples)
105
106 var c = 0
107 while UpdateInputs() and c < nFrames:
108 WithNextFrame(swapchain, framebuffer, commandbuffer):
109 WithRenderPass(mainRenderpass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)):
110 WithPipeline(commandbuffer, pipeline):
111 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad, instances = instancesA)
112 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad, instances = instancesB)
113 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = tri, instances = instancesA)
114 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = tri, instances = instancesB)
115 inc c
116
117 # cleanup
118 checkVkResult vkDeviceWaitIdle(vulkan.device)
119 DestroyPipeline(pipeline)
120 DestroyRenderData(renderdata)
121
122 proc test_03_global_descriptorset(nFrames: int) =
123 var renderdata = InitRenderData()
124
125 type
126 RenderSettings = object
127 gamma: float32
128 FirstDS = object
129 settings: GPUValue[RenderSettings, UniformBuffer]
130 QuadShader = object
131 position {.VertexAttribute.}: Vec3f
132 color {.VertexAttribute.}: Vec3f
133 fragmentColor {.Pass.}: Vec3f
134 outColor {.ShaderOutput.}: Vec4f
135 firstDS: DescriptorSet[FirstDS, First]
136 # code
137 vertexCode: string = """void main() {
138 fragmentColor = vec3(pow(color.r, settings.gamma), pow(color.g, settings.gamma), pow(color.b, settings.gamma));
139 gl_Position = vec4(position, 1);}"""
140 fragmentCode: string = """void main() {
141 outColor = vec4(fragmentColor, 1);}"""
142 QuadMesh = object
143 position: GPUArray[Vec3f, VertexBuffer]
144 color: GPUArray[Vec3f, VertexBuffer]
145 indices: GPUArray[uint16, IndexBuffer]
146
147 var quad = QuadMesh(
148 position: asGPUArray([NewVec3f(-0.3, -0.3), NewVec3f(-0.3, 0.3), NewVec3f(0.3, 0.3), NewVec3f(0.3, -0.3)], VertexBuffer),
149 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer),
150 color: asGPUArray([NewVec3f(1, 1, 1), NewVec3f(1, 1, 1), NewVec3f(1, 1, 1), NewVec3f(1, 1, 1)], VertexBuffer),
151 )
152 var firstDs = DescriptorSet[FirstDS, First](
153 data: FirstDS(
154 settings: asGPUValue(RenderSettings(
155 gamma: 1.0'f32
156 ), UniformBuffer)
157 )
158 )
159 AssignBuffers(renderdata, quad)
160 AssignBuffers(renderdata, firstDs)
161 renderdata.FlushAllMemory()
162
163 var pipeline = CreatePipeline[QuadShader](renderPass = mainRenderpass, samples = swapchain.samples)
164
165 var c = 0
166 while UpdateInputs() and c < nFrames:
167 WithNextFrame(swapchain, framebuffer, commandbuffer):
168 WithBind(commandbuffer, firstDs, pipeline, swapchain.currentFiF):
169 WithRenderPass(mainRenderpass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)):
170 WithPipeline(commandbuffer, pipeline):
171 Render(commandbuffer = commandbuffer, pipeline = pipeline, firstSet = firstDs, mesh = quad)
172 inc c
173
174 # cleanup
175 checkVkResult vkDeviceWaitIdle(vulkan.device)
176 DestroyPipeline(pipeline)
177 DestroyRenderData(renderdata)
178
54 when isMainModule: 179 when isMainModule:
55 mainRenderpass = CreatePresentationRenderPass() 180 var nFrames = 100
56 swapchain = InitSwapchain(renderpass = mainRenderpass).get() 181 InitVulkan()
57 182
58 test_01_gl_triangle() 183 # test normal
59 184 block:
60 checkVkResult vkDeviceWaitIdle(vulkan.device) 185 mainRenderpass = CreatePresentationRenderPass()
61 vkDestroyRenderPass(vulkan.device, mainRenderpass, nil) 186 swapchain = InitSwapchain(renderpass = mainRenderpass).get()
62 DestroySwapchain(swapchain) 187
188 # tests a simple triangle with minimalistic shader and vertex format
189 test_01_triangle(nFrames)
190
191 # tests instanced triangles and quads, mixing meshes and instances
192 test_02_triangle_quad_instanced(nFrames)
193
194 # tests
195 test_03_global_descriptorset(nFrames)
196
197 checkVkResult vkDeviceWaitIdle(vulkan.device)
198 vkDestroyRenderPass(vulkan.device, mainRenderpass, nil)
199 DestroySwapchain(swapchain)
200
201 # test MSAA
202 block:
203 mainRenderpass = CreatePresentationRenderPass(samples = VK_SAMPLE_COUNT_4_BIT)
204 swapchain = InitSwapchain(renderpass = mainRenderpass, samples = VK_SAMPLE_COUNT_4_BIT).get()
205
206 test_01_triangle(nFrames)
207
208 checkVkResult vkDeviceWaitIdle(vulkan.device)
209 vkDestroyRenderPass(vulkan.device, mainRenderpass, nil)
210 DestroySwapchain(swapchain)
211
63 DestroyVulkan() 212 DestroyVulkan()