Mercurial > games > semicongine
annotate tests/test_rendering.nim @ 1216:8b5558b29387 compiletime-tests
did: rename base package file
| author | sam <sam@basx.dev> |
|---|---|
| date | Wed, 17 Jul 2024 21:00:37 +0700 |
| parents | d9799f74f5a7 |
| children | 518a952eccbf |
| rev | line source |
|---|---|
| 1203 | 1 import std/options |
| 1204 | 2 import std/random |
| 3 | |
| 1203 | 4 import ../semicongine |
| 5 | |
| 6 var | |
| 7 mainRenderpass: VkRenderPass | |
| 8 swapchain: Swapchain | |
| 9 | |
| 1204 | 10 proc test_01_triangle(nFrames: int) = |
| 1203 | 11 var renderdata = InitRenderData() |
| 12 | |
| 13 type | |
| 14 TrianglShader = object | |
| 15 position {.VertexAttribute.}: Vec3f | |
| 16 color {.VertexAttribute.}: Vec3f | |
| 17 fragmentColor {.Pass.}: Vec3f | |
| 18 outColor {.ShaderOutput.}: Vec4f | |
| 19 # code | |
| 20 vertexCode: string = """void main() { | |
| 21 fragmentColor = color; | |
| 22 gl_Position = vec4(position, 1);}""" | |
| 23 fragmentCode: string = """void main() { | |
| 24 outColor = vec4(fragmentColor, 1);}""" | |
| 25 TriangleMesh = object | |
| 26 position: GPUArray[Vec3f, VertexBuffer] | |
| 27 color: GPUArray[Vec3f, VertexBuffer] | |
| 28 var mesh = TriangleMesh( | |
| 1204 | 29 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(0, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer), |
| 1203 | 30 color: asGPUArray([NewVec3f(0, 0, 1), NewVec3f(0, 1, 0), NewVec3f(1, 0, 0)], VertexBuffer), |
| 31 ) | |
| 1204 | 32 AssignBuffers(renderdata, mesh) |
| 33 renderdata.FlushAllMemory() | |
| 1203 | 34 |
| 35 var | |
| 1204 | 36 pipeline = CreatePipeline[TrianglShader](renderPass = mainRenderpass, samples = swapchain.samples) |
| 1203 | 37 |
| 1204 | 38 var c = 0 |
| 39 while UpdateInputs() and c < nFrames: | |
| 1203 | 40 WithNextFrame(swapchain, framebuffer, commandbuffer): |
| 41 WithRenderPass(mainRenderpass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): | |
| 42 WithPipeline(commandbuffer, pipeline): | |
| 1204 | 43 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh) |
| 44 inc c | |
| 1203 | 45 |
| 46 # cleanup | |
| 1204 | 47 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 1203 | 48 DestroyPipeline(pipeline) |
| 49 DestroyRenderData(renderdata) | |
| 50 | |
| 51 | |
| 1204 | 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 | |
| 1210 | 122 proc test_03_simple_descriptorset(nFrames: int) = |
| 123 var renderdata = InitRenderData() | |
| 124 | |
| 125 type | |
| 126 Material = object | |
| 127 baseColor: Vec3f | |
| 128 | |
| 129 Uniforms = object | |
| 130 material: GPUValue[Material, UniformBuffer] | |
| 131 texture1: Texture[TVec3[uint8]] | |
| 132 | |
| 133 QuadShader = object | |
| 134 position {.VertexAttribute.}: Vec3f | |
| 135 fragmentColor {.Pass.}: Vec3f | |
| 136 uv {.Pass.}: Vec2f | |
| 137 outColor {.ShaderOutput.}: Vec4f | |
| 138 descriptorSets {.DescriptorSets.}: (Uniforms, ) | |
| 139 # code | |
| 140 vertexCode: string = """void main() { | |
| 141 fragmentColor = material.baseColor; | |
| 142 gl_Position = vec4(position, 1); | |
| 143 gl_Position.x += ((material.baseColor.b - 0.5) * 2) - 0.5; | |
| 144 uv = position.xy + 0.5; | |
| 145 }""" | |
| 146 fragmentCode: string = """void main() { | |
| 147 outColor = vec4(fragmentColor, 1) * texture(texture1, uv);}""" | |
| 148 QuadMesh = object | |
| 149 position: GPUArray[Vec3f, VertexBuffer] | |
| 150 indices: GPUArray[uint16, IndexBuffer] | |
| 151 | |
| 152 let R = TVec3[uint8]([255'u8, 0'u8, 0'u8]) | |
| 153 let G = TVec3[uint8]([0'u8, 255'u8, 0'u8]) | |
| 154 let B = TVec3[uint8]([0'u8, 0'u8, 255'u8]) | |
| 155 let W = TVec3[uint8]([255'u8, 255'u8, 255'u8]) | |
| 156 var | |
| 157 quad = QuadMesh( | |
| 158 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(-0.5, 0.5), NewVec3f(0.5, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer), | |
| 159 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer), | |
| 160 ) | |
| 161 uniforms1 = asDescriptorSet( | |
| 162 Uniforms( | |
| 163 material: asGPUValue(Material(baseColor: NewVec3f(1, 1, 1)), UniformBuffer), | |
| 164 texture1: Texture[TVec3[uint8]](width: 3, height: 3, data: @[R, G, B, G, B, R, B, R, G], interpolation: VK_FILTER_NEAREST), | |
| 165 ) | |
| 166 ) | |
| 167 uniforms2 = asDescriptorSet( | |
| 168 Uniforms( | |
| 169 material: asGPUValue(Material(baseColor: NewVec3f(0.5, 0.5, 0.5)), UniformBuffer), | |
| 170 texture1: Texture[TVec3[uint8]](width: 2, height: 2, data: @[R, G, B, W]), | |
| 171 ) | |
| 172 ) | |
| 173 | |
| 174 AssignBuffers(renderdata, quad) | |
| 175 AssignBuffers(renderdata, uniforms1) | |
| 176 AssignBuffers(renderdata, uniforms2) | |
| 177 UploadTextures(renderdata, uniforms1) | |
| 178 UploadTextures(renderdata, uniforms2) | |
| 179 renderdata.FlushAllMemory() | |
| 180 | |
| 181 var pipeline = CreatePipeline[QuadShader](renderPass = mainRenderpass, samples = swapchain.samples) | |
| 182 | |
| 183 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], uniforms1) | |
| 184 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], uniforms2) | |
| 185 | |
| 186 var c = 0 | |
| 187 while UpdateInputs() and c < nFrames: | |
| 188 WithNextFrame(swapchain, framebuffer, commandbuffer): | |
| 189 WithRenderPass(mainRenderpass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): | |
| 190 WithPipeline(commandbuffer, pipeline): | |
| 191 WithBind(commandbuffer, (uniforms1, ), pipeline, swapchain.currentFiF): | |
| 192 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) | |
| 193 WithBind(commandbuffer, (uniforms2, ), pipeline, swapchain.currentFiF): | |
| 194 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) | |
| 195 inc c | |
| 196 | |
| 197 # cleanup | |
| 198 checkVkResult vkDeviceWaitIdle(vulkan.device) | |
| 199 DestroyPipeline(pipeline) | |
| 200 DestroyRenderData(renderdata) | |
| 201 | |
| 202 proc test_04_multiple_descriptorsets(nFrames: int) = | |
| 1204 | 203 var renderdata = InitRenderData() |
| 1203 | 204 |
| 1204 | 205 type |
| 206 RenderSettings = object | |
| 1209 | 207 brigthness: float32 |
| 1210 | 208 Material = object |
| 209 baseColor: Vec3f | |
| 1209 | 210 ObjectSettings = object |
| 1210 | 211 scale: float32 |
| 212 materialIndex: uint32 | |
| 213 Constants = object | |
| 214 offset: Vec2f | |
| 215 | |
| 216 ConstSet = object | |
| 217 constants: GPUValue[Constants, UniformBuffer] | |
| 1209 | 218 MainSet = object |
| 219 renderSettings: GPUValue[RenderSettings, UniformBufferMapped] | |
| 1210 | 220 material: array[2, GPUValue[Material, UniformBuffer]] |
| 221 texture1: array[2, Texture[TVec1[uint8]]] | |
| 1209 | 222 OtherSet = object |
| 1210 | 223 objectSettings: GPUValue[ObjectSettings, UniformBufferMapped] |
| 1209 | 224 |
| 1204 | 225 QuadShader = object |
| 226 position {.VertexAttribute.}: Vec3f | |
| 227 fragmentColor {.Pass.}: Vec3f | |
| 1210 | 228 uv {.Pass.}: Vec2f |
| 1204 | 229 outColor {.ShaderOutput.}: Vec4f |
| 1210 | 230 descriptorSets {.DescriptorSets.}: (ConstSet, MainSet, OtherSet) |
| 1204 | 231 # code |
| 232 vertexCode: string = """void main() { | |
| 1210 | 233 fragmentColor = material[objectSettings.materialIndex].baseColor * renderSettings.brigthness; |
| 234 gl_Position = vec4(position * objectSettings.scale, 1); | |
| 235 gl_Position.xy += constants.offset.xy; | |
| 236 gl_Position.x += material[objectSettings.materialIndex].baseColor.b - 0.5; | |
| 237 uv = position.xy + 0.5; | |
| 238 }""" | |
| 1204 | 239 fragmentCode: string = """void main() { |
| 1210 | 240 outColor = vec4(fragmentColor * texture(texture1[objectSettings.materialIndex], uv).rrr, 1); |
| 241 }""" | |
| 1204 | 242 QuadMesh = object |
| 243 position: GPUArray[Vec3f, VertexBuffer] | |
| 244 indices: GPUArray[uint16, IndexBuffer] | |
| 1203 | 245 |
| 1204 | 246 var quad = QuadMesh( |
| 1209 | 247 position: asGPUArray([NewVec3f(-0.5, -0.5), NewVec3f(-0.5, 0.5), NewVec3f(0.5, 0.5), NewVec3f(0.5, -0.5)], VertexBuffer), |
| 1204 | 248 indices: asGPUArray([0'u16, 1'u16, 2'u16, 2'u16, 3'u16, 0'u16], IndexBuffer), |
| 1209 | 249 ) |
| 1210 | 250 var constset = asDescriptorSet( |
| 251 ConstSet( | |
| 252 constants: asGPUValue(Constants(offset: NewVec2f(-0.3, 0.2)), UniformBuffer), | |
| 253 ) | |
| 254 ) | |
| 255 let G = TVec1[uint8]([50'u8]) | |
| 256 let W = TVec1[uint8]([255'u8]) | |
| 257 var mainset = asDescriptorSet( | |
| 1209 | 258 MainSet( |
| 259 renderSettings: asGPUValue(RenderSettings(brigthness: 0), UniformBufferMapped), | |
| 1210 | 260 material: [ |
| 261 asGPUValue(Material(baseColor: NewVec3f(1, 1, 0)), UniformBuffer), | |
| 262 asGPUValue(Material(baseColor: NewVec3f(1, 0, 1)), UniformBuffer), | |
| 263 ], | |
| 264 texture1: [ | |
| 265 Texture[TVec1[uint8]](width: 2, height: 2, data: @[W, G, G, W], interpolation: VK_FILTER_NEAREST), | |
| 266 Texture[TVec1[uint8]](width: 3, height: 3, data: @[W, G, W, G, W, G, W, G, W], interpolation: VK_FILTER_NEAREST), | |
| 267 ], | |
| 268 ), | |
| 269 ) | |
| 270 var otherset1 = asDescriptorSet( | |
| 271 OtherSet( | |
| 272 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 0), UniformBufferMapped), | |
| 1209 | 273 ) |
| 1204 | 274 ) |
| 1210 | 275 var otherset2 = asDescriptorSet( |
| 1209 | 276 OtherSet( |
| 1210 | 277 objectSettings: asGPUValue(ObjectSettings(scale: 1.0, materialIndex: 1), UniformBufferMapped), |
| 1209 | 278 ) |
| 1204 | 279 ) |
| 1209 | 280 |
| 1204 | 281 AssignBuffers(renderdata, quad) |
| 1210 | 282 AssignBuffers(renderdata, constset) |
| 283 AssignBuffers(renderdata, mainset) | |
| 284 AssignBuffers(renderdata, otherset1) | |
| 285 AssignBuffers(renderdata, otherset2) | |
| 286 UploadTextures(renderdata, mainset) | |
| 1204 | 287 renderdata.FlushAllMemory() |
| 288 | |
| 289 var pipeline = CreatePipeline[QuadShader](renderPass = mainRenderpass, samples = swapchain.samples) | |
| 290 | |
| 1210 | 291 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[0], constset) |
| 292 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[1], mainset) | |
| 293 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset1) | |
| 294 InitDescriptorSet(renderdata, pipeline.descriptorSetLayouts[2], otherset2) | |
|
1205
f7530247a21f
did: improve descriptor-set handling, add simple descriptor set test
sam <sam@basx.dev>
parents:
1204
diff
changeset
|
295 |
| 1204 | 296 var c = 0 |
| 297 while UpdateInputs() and c < nFrames: | |
| 298 WithNextFrame(swapchain, framebuffer, commandbuffer): | |
| 1210 | 299 WithRenderPass(mainRenderpass, framebuffer, commandbuffer, swapchain.width, swapchain.height, NewVec4f(0, 0, 0, 0)): |
| 300 WithPipeline(commandbuffer, pipeline): | |
| 301 WithBind(commandbuffer, (constset, mainset, otherset1), pipeline, swapchain.currentFiF): | |
| 302 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) | |
| 303 WithBind(commandbuffer, (constset, mainset, otherset2), pipeline, swapchain.currentFiF): | |
| 304 Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = quad) | |
| 305 mainset.data.renderSettings.data.brigthness = (c.float32 / nFrames.float32) | |
| 306 otherset1.data.objectSettings.data.scale = 0.5 + (c.float32 / nFrames.float32) | |
| 307 UpdateGPUBuffer(mainset.data.renderSettings) | |
| 308 UpdateGPUBuffer(otherset1.data.objectSettings) | |
|
1205
f7530247a21f
did: improve descriptor-set handling, add simple descriptor set test
sam <sam@basx.dev>
parents:
1204
diff
changeset
|
309 renderdata.FlushAllMemory() |
| 1204 | 310 inc c |
| 311 | |
| 312 # cleanup | |
| 1203 | 313 checkVkResult vkDeviceWaitIdle(vulkan.device) |
| 1204 | 314 DestroyPipeline(pipeline) |
| 315 DestroyRenderData(renderdata) | |
| 316 | |
| 317 when isMainModule: | |
| 1211 | 318 var nFrames = 2000 |
| 1204 | 319 InitVulkan() |
| 320 | |
| 321 # test normal | |
| 322 block: | |
| 323 mainRenderpass = CreatePresentationRenderPass() | |
| 324 swapchain = InitSwapchain(renderpass = mainRenderpass).get() | |
| 325 | |
| 326 # tests a simple triangle with minimalistic shader and vertex format | |
| 1211 | 327 test_01_triangle(nFrames) |
| 1204 | 328 |
| 329 # tests instanced triangles and quads, mixing meshes and instances | |
| 1211 | 330 test_02_triangle_quad_instanced(nFrames) |
| 1204 | 331 |
| 1211 | 332 # teste descriptor sets |
| 333 test_03_simple_descriptorset(nFrames) | |
| 1210 | 334 |
| 1211 | 335 # tests multiple descriptor sets and arrays |
| 1210 | 336 test_04_multiple_descriptorsets(nFrames) |
| 1204 | 337 |
| 338 checkVkResult vkDeviceWaitIdle(vulkan.device) | |
| 339 vkDestroyRenderPass(vulkan.device, mainRenderpass, nil) | |
| 340 DestroySwapchain(swapchain) | |
| 341 | |
| 342 # test MSAA | |
| 343 block: | |
| 344 mainRenderpass = CreatePresentationRenderPass(samples = VK_SAMPLE_COUNT_4_BIT) | |
| 345 swapchain = InitSwapchain(renderpass = mainRenderpass, samples = VK_SAMPLE_COUNT_4_BIT).get() | |
| 346 | |
| 1211 | 347 test_01_triangle(99999999) |
| 1204 | 348 |
| 349 checkVkResult vkDeviceWaitIdle(vulkan.device) | |
| 350 vkDestroyRenderPass(vulkan.device, mainRenderpass, nil) | |
| 351 DestroySwapchain(swapchain) | |
| 352 | |
| 1203 | 353 DestroyVulkan() |
