vulkan-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.simplecov +6 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +51 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +93 -0
  9. data/Rakefile +14 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +9 -0
  12. data/bin/setup.bat +2 -0
  13. data/examples/models/viking_room.obj +16053 -0
  14. data/examples/screenshots/vt10-viking_room.png +0 -0
  15. data/examples/shaders/depth_buffering.vert +25 -0
  16. data/examples/shaders/depth_buffering.vert.spv +0 -0
  17. data/examples/shaders/model_loading.frag +13 -0
  18. data/examples/shaders/model_loading.frag.spv +0 -0
  19. data/examples/shaders/model_loading.vert +25 -0
  20. data/examples/shaders/model_loading.vert.spv +0 -0
  21. data/examples/shaders/textures.frag +13 -0
  22. data/examples/shaders/textures.frag.spv +0 -0
  23. data/examples/shaders/textures.vert +25 -0
  24. data/examples/shaders/textures.vert.spv +0 -0
  25. data/examples/shaders/triangle.frag +10 -0
  26. data/examples/shaders/triangle.frag.spv +0 -0
  27. data/examples/shaders/triangle.vert +25 -0
  28. data/examples/shaders/triangle.vert.spv +0 -0
  29. data/examples/shaders/uniform_buffer.vert +22 -0
  30. data/examples/shaders/uniform_buffer.vert.spv +0 -0
  31. data/examples/shaders/vertex_buffer.vert +16 -0
  32. data/examples/shaders/vertex_buffer.vert.spv +0 -0
  33. data/examples/textures/texture.png +0 -0
  34. data/examples/textures/viking_room.png +0 -0
  35. data/examples/vt00_dump_info.rb +24 -0
  36. data/examples/vt01_triangle.rb +140 -0
  37. data/examples/vt02_vertex_buffer_triangle_host_visible.rb +164 -0
  38. data/examples/vt03_vertex_buffer_triangle_device_local.rb +174 -0
  39. data/examples/vt04_index_buffer_device_local.rb +193 -0
  40. data/examples/vt05_uniform_buffers.rb +237 -0
  41. data/examples/vt06_textures.rb +275 -0
  42. data/examples/vt07_depth_buffering.rb +315 -0
  43. data/examples/vt08_model_loading.rb +321 -0
  44. data/examples/vt09_mipmaps.rb +329 -0
  45. data/examples/vt10_multisampling.rb +344 -0
  46. data/lib/fiddle_ext.rb +15 -0
  47. data/lib/vulkan/buffer.rb +66 -0
  48. data/lib/vulkan/buffer_memory.rb +13 -0
  49. data/lib/vulkan/checks.rb +12 -0
  50. data/lib/vulkan/command_buffer.rb +380 -0
  51. data/lib/vulkan/command_pool.rb +28 -0
  52. data/lib/vulkan/conversions.rb +511 -0
  53. data/lib/vulkan/descriptor_pool.rb +45 -0
  54. data/lib/vulkan/descriptor_set.rb +86 -0
  55. data/lib/vulkan/descriptor_set_layout.rb +39 -0
  56. data/lib/vulkan/dispatch_table.rb +78 -0
  57. data/lib/vulkan/error.rb +43 -0
  58. data/lib/vulkan/fence.rb +32 -0
  59. data/lib/vulkan/finalizer.rb +43 -0
  60. data/lib/vulkan/framebuffer.rb +37 -0
  61. data/lib/vulkan/generated/commands.rb +298 -0
  62. data/lib/vulkan/generated/enums.rb +1049 -0
  63. data/lib/vulkan/generated/extensions/reserved_do_not_use_146.rb +8 -0
  64. data/lib/vulkan/generated/extensions/reserved_do_not_use_94.rb +8 -0
  65. data/lib/vulkan/generated/extensions/vk_amd_buffer_marker.rb +10 -0
  66. data/lib/vulkan/generated/extensions/vk_amd_draw_indirect_count.rb +10 -0
  67. data/lib/vulkan/generated/extensions/vk_amd_extension_134.rb +10 -0
  68. data/lib/vulkan/generated/extensions/vk_amd_extension_135.rb +10 -0
  69. data/lib/vulkan/generated/extensions/vk_amd_extension_136.rb +10 -0
  70. data/lib/vulkan/generated/extensions/vk_amd_extension_140.rb +10 -0
  71. data/lib/vulkan/generated/extensions/vk_amd_extension_142.rb +10 -0
  72. data/lib/vulkan/generated/extensions/vk_amd_extension_143.rb +10 -0
  73. data/lib/vulkan/generated/extensions/vk_amd_extension_17.rb +10 -0
  74. data/lib/vulkan/generated/extensions/vk_amd_extension_18.rb +10 -0
  75. data/lib/vulkan/generated/extensions/vk_amd_extension_182.rb +10 -0
  76. data/lib/vulkan/generated/extensions/vk_amd_extension_183.rb +10 -0
  77. data/lib/vulkan/generated/extensions/vk_amd_extension_184.rb +10 -0
  78. data/lib/vulkan/generated/extensions/vk_amd_extension_187.rb +10 -0
  79. data/lib/vulkan/generated/extensions/vk_amd_extension_188.rb +10 -0
  80. data/lib/vulkan/generated/extensions/vk_amd_extension_189.rb +10 -0
  81. data/lib/vulkan/generated/extensions/vk_amd_extension_20.rb +10 -0
  82. data/lib/vulkan/generated/extensions/vk_amd_extension_214.rb +10 -0
  83. data/lib/vulkan/generated/extensions/vk_amd_extension_226.rb +10 -0
  84. data/lib/vulkan/generated/extensions/vk_amd_extension_227.rb +10 -0
  85. data/lib/vulkan/generated/extensions/vk_amd_extension_228.rb +10 -0
  86. data/lib/vulkan/generated/extensions/vk_amd_extension_229.rb +10 -0
  87. data/lib/vulkan/generated/extensions/vk_amd_extension_230.rb +10 -0
  88. data/lib/vulkan/generated/extensions/vk_amd_extension_231.rb +10 -0
  89. data/lib/vulkan/generated/extensions/vk_amd_extension_232.rb +10 -0
  90. data/lib/vulkan/generated/extensions/vk_amd_extension_233.rb +10 -0
  91. data/lib/vulkan/generated/extensions/vk_amd_extension_234.rb +10 -0
  92. data/lib/vulkan/generated/extensions/vk_amd_extension_235.rb +10 -0
  93. data/lib/vulkan/generated/extensions/vk_amd_extension_236.rb +10 -0
  94. data/lib/vulkan/generated/extensions/vk_amd_extension_24.rb +10 -0
  95. data/lib/vulkan/generated/extensions/vk_amd_extension_25.rb +10 -0
  96. data/lib/vulkan/generated/extensions/vk_amd_extension_32.rb +10 -0
  97. data/lib/vulkan/generated/extensions/vk_amd_extension_33.rb +10 -0
  98. data/lib/vulkan/generated/extensions/vk_amd_extension_35.rb +10 -0
  99. data/lib/vulkan/generated/extensions/vk_amd_extension_39.rb +10 -0
  100. data/lib/vulkan/generated/extensions/vk_amd_extension_40.rb +10 -0
  101. data/lib/vulkan/generated/extensions/vk_amd_extension_41.rb +10 -0
  102. data/lib/vulkan/generated/extensions/vk_amd_extension_44.rb +10 -0
  103. data/lib/vulkan/generated/extensions/vk_amd_extension_45.rb +10 -0
  104. data/lib/vulkan/generated/extensions/vk_amd_extension_46.rb +10 -0
  105. data/lib/vulkan/generated/extensions/vk_amd_gcn_shader.rb +10 -0
  106. data/lib/vulkan/generated/extensions/vk_amd_gpu_shader_half_float.rb +10 -0
  107. data/lib/vulkan/generated/extensions/vk_amd_gpu_shader_int16.rb +10 -0
  108. data/lib/vulkan/generated/extensions/vk_amd_memory_overallocation_behavior.rb +11 -0
  109. data/lib/vulkan/generated/extensions/vk_amd_mixed_attachment_samples.rb +10 -0
  110. data/lib/vulkan/generated/extensions/vk_amd_negative_viewport_height.rb +10 -0
  111. data/lib/vulkan/generated/extensions/vk_amd_rasterization_order.rb +11 -0
  112. data/lib/vulkan/generated/extensions/vk_amd_shader_ballot.rb +10 -0
  113. data/lib/vulkan/generated/extensions/vk_amd_shader_core_properties.rb +11 -0
  114. data/lib/vulkan/generated/extensions/vk_amd_shader_explicit_vertex_parameter.rb +10 -0
  115. data/lib/vulkan/generated/extensions/vk_amd_shader_fragment_mask.rb +10 -0
  116. data/lib/vulkan/generated/extensions/vk_amd_shader_image_load_store_lod.rb +10 -0
  117. data/lib/vulkan/generated/extensions/vk_amd_shader_info.rb +10 -0
  118. data/lib/vulkan/generated/extensions/vk_amd_shader_trinary_minmax.rb +10 -0
  119. data/lib/vulkan/generated/extensions/vk_amd_texture_gather_bias_lod.rb +11 -0
  120. data/lib/vulkan/generated/extensions/vk_android_external_memory_android_hardware_buffer.rb +17 -0
  121. data/lib/vulkan/generated/extensions/vk_android_native_buffer.rb +12 -0
  122. data/lib/vulkan/generated/extensions/vk_arm_extension_01.rb +10 -0
  123. data/lib/vulkan/generated/extensions/vk_arm_extension_198.rb +10 -0
  124. data/lib/vulkan/generated/extensions/vk_ext_acquire_xlib_display.rb +10 -0
  125. data/lib/vulkan/generated/extensions/vk_ext_astc_decode_mode.rb +12 -0
  126. data/lib/vulkan/generated/extensions/vk_ext_blend_operation_advanced.rb +60 -0
  127. data/lib/vulkan/generated/extensions/vk_ext_calibrated_timestamps.rb +11 -0
  128. data/lib/vulkan/generated/extensions/vk_ext_conditional_rendering.rb +16 -0
  129. data/lib/vulkan/generated/extensions/vk_ext_conservative_rasterization.rb +12 -0
  130. data/lib/vulkan/generated/extensions/vk_ext_debug_marker.rb +13 -0
  131. data/lib/vulkan/generated/extensions/vk_ext_debug_report.rb +16 -0
  132. data/lib/vulkan/generated/extensions/vk_ext_debug_utils.rb +16 -0
  133. data/lib/vulkan/generated/extensions/vk_ext_depth_range_unrestricted.rb +10 -0
  134. data/lib/vulkan/generated/extensions/vk_ext_descriptor_indexing.rb +18 -0
  135. data/lib/vulkan/generated/extensions/vk_ext_direct_mode_display.rb +10 -0
  136. data/lib/vulkan/generated/extensions/vk_ext_discard_rectangles.rb +13 -0
  137. data/lib/vulkan/generated/extensions/vk_ext_display_control.rb +14 -0
  138. data/lib/vulkan/generated/extensions/vk_ext_display_surface_counter.rb +12 -0
  139. data/lib/vulkan/generated/extensions/vk_ext_extension_160.rb +10 -0
  140. data/lib/vulkan/generated/extensions/vk_ext_extension_176.rb +10 -0
  141. data/lib/vulkan/generated/extensions/vk_ext_extension_177.rb +10 -0
  142. data/lib/vulkan/generated/extensions/vk_ext_extension_219.rb +15 -0
  143. data/lib/vulkan/generated/extensions/vk_ext_extension_220.rb +10 -0
  144. data/lib/vulkan/generated/extensions/vk_ext_extension_222.rb +10 -0
  145. data/lib/vulkan/generated/extensions/vk_ext_extension_223.rb +10 -0
  146. data/lib/vulkan/generated/extensions/vk_ext_extension_28.rb +10 -0
  147. data/lib/vulkan/generated/extensions/vk_ext_external_memory_dma_buf.rb +11 -0
  148. data/lib/vulkan/generated/extensions/vk_ext_external_memory_host.rb +15 -0
  149. data/lib/vulkan/generated/extensions/vk_ext_global_priority.rb +12 -0
  150. data/lib/vulkan/generated/extensions/vk_ext_hdr_metadata.rb +11 -0
  151. data/lib/vulkan/generated/extensions/vk_ext_image_drm_format_modifier.rb +24 -0
  152. data/lib/vulkan/generated/extensions/vk_ext_inline_uniform_block.rb +15 -0
  153. data/lib/vulkan/generated/extensions/vk_ext_macos_ios_window.rb +10 -0
  154. data/lib/vulkan/generated/extensions/vk_ext_pci_bus_info.rb +11 -0
  155. data/lib/vulkan/generated/extensions/vk_ext_post_depth_coverage.rb +10 -0
  156. data/lib/vulkan/generated/extensions/vk_ext_queue_family_foreign.rb +11 -0
  157. data/lib/vulkan/generated/extensions/vk_ext_sample_locations.rb +17 -0
  158. data/lib/vulkan/generated/extensions/vk_ext_sampler_filter_minmax.rb +13 -0
  159. data/lib/vulkan/generated/extensions/vk_ext_shader_stencil_export.rb +10 -0
  160. data/lib/vulkan/generated/extensions/vk_ext_shader_subgroup_ballot.rb +10 -0
  161. data/lib/vulkan/generated/extensions/vk_ext_shader_subgroup_vote.rb +10 -0
  162. data/lib/vulkan/generated/extensions/vk_ext_shader_viewport_index_layer.rb +10 -0
  163. data/lib/vulkan/generated/extensions/vk_ext_swapchain_colorspace.rb +24 -0
  164. data/lib/vulkan/generated/extensions/vk_ext_transform_feedback.rb +20 -0
  165. data/lib/vulkan/generated/extensions/vk_ext_validation_cache.rb +13 -0
  166. data/lib/vulkan/generated/extensions/vk_ext_validation_flags.rb +11 -0
  167. data/lib/vulkan/generated/extensions/vk_ext_vertex_attribute_divisor.rb +13 -0
  168. data/lib/vulkan/generated/extensions/vk_fuchsia_imagepipe_surface.rb +11 -0
  169. data/lib/vulkan/generated/extensions/vk_google_decorate_string.rb +10 -0
  170. data/lib/vulkan/generated/extensions/vk_google_display_timing.rb +11 -0
  171. data/lib/vulkan/generated/extensions/vk_google_extension_192.rb +10 -0
  172. data/lib/vulkan/generated/extensions/vk_google_extension_193.rb +10 -0
  173. data/lib/vulkan/generated/extensions/vk_google_extension_194.rb +10 -0
  174. data/lib/vulkan/generated/extensions/vk_google_extension_195.rb +10 -0
  175. data/lib/vulkan/generated/extensions/vk_google_extension_196.rb +10 -0
  176. data/lib/vulkan/generated/extensions/vk_google_extension_216.rb +10 -0
  177. data/lib/vulkan/generated/extensions/vk_google_extension_217.rb +10 -0
  178. data/lib/vulkan/generated/extensions/vk_google_extension_49.rb +10 -0
  179. data/lib/vulkan/generated/extensions/vk_google_extension_50.rb +10 -0
  180. data/lib/vulkan/generated/extensions/vk_google_hlsl_functionality1.rb +10 -0
  181. data/lib/vulkan/generated/extensions/vk_img_extension_107.rb +10 -0
  182. data/lib/vulkan/generated/extensions/vk_img_extension_108.rb +10 -0
  183. data/lib/vulkan/generated/extensions/vk_img_extension_109.rb +10 -0
  184. data/lib/vulkan/generated/extensions/vk_img_extension_111.rb +10 -0
  185. data/lib/vulkan/generated/extensions/vk_img_extension_69.rb +10 -0
  186. data/lib/vulkan/generated/extensions/vk_img_filter_cubic.rb +12 -0
  187. data/lib/vulkan/generated/extensions/vk_img_format_pvrtc.rb +18 -0
  188. data/lib/vulkan/generated/extensions/vk_intel_extension_210.rb +10 -0
  189. data/lib/vulkan/generated/extensions/vk_intel_extension_211.rb +10 -0
  190. data/lib/vulkan/generated/extensions/vk_intel_extension_243.rb +10 -0
  191. data/lib/vulkan/generated/extensions/vk_khr_16bit_storage.rb +11 -0
  192. data/lib/vulkan/generated/extensions/vk_khr_8bit_storage.rb +11 -0
  193. data/lib/vulkan/generated/extensions/vk_khr_android_surface.rb +11 -0
  194. data/lib/vulkan/generated/extensions/vk_khr_bind_memory2.rb +13 -0
  195. data/lib/vulkan/generated/extensions/vk_khr_create_renderpass2.rb +17 -0
  196. data/lib/vulkan/generated/extensions/vk_khr_dedicated_allocation.rb +12 -0
  197. data/lib/vulkan/generated/extensions/vk_khr_descriptor_update_template.rb +15 -0
  198. data/lib/vulkan/generated/extensions/vk_khr_device_group.rb +33 -0
  199. data/lib/vulkan/generated/extensions/vk_khr_device_group_creation.rb +14 -0
  200. data/lib/vulkan/generated/extensions/vk_khr_display.rb +14 -0
  201. data/lib/vulkan/generated/extensions/vk_khr_display_swapchain.rb +12 -0
  202. data/lib/vulkan/generated/extensions/vk_khr_draw_indirect_count.rb +10 -0
  203. data/lib/vulkan/generated/extensions/vk_khr_driver_properties.rb +13 -0
  204. data/lib/vulkan/generated/extensions/vk_khr_extension_117.rb +10 -0
  205. data/lib/vulkan/generated/extensions/vk_khr_extension_119.rb +10 -0
  206. data/lib/vulkan/generated/extensions/vk_khr_extension_200.rb +10 -0
  207. data/lib/vulkan/generated/extensions/vk_khr_extension_201.rb +10 -0
  208. data/lib/vulkan/generated/extensions/vk_khr_extension_208.rb +10 -0
  209. data/lib/vulkan/generated/extensions/vk_khr_extension_209.rb +10 -0
  210. data/lib/vulkan/generated/extensions/vk_khr_extension_221.rb +11 -0
  211. data/lib/vulkan/generated/extensions/vk_khr_extension_237.rb +10 -0
  212. data/lib/vulkan/generated/extensions/vk_khr_extension_238.rb +10 -0
  213. data/lib/vulkan/generated/extensions/vk_khr_extension_239.rb +10 -0
  214. data/lib/vulkan/generated/extensions/vk_khr_extension_240.rb +10 -0
  215. data/lib/vulkan/generated/extensions/vk_khr_extension_83.rb +10 -0
  216. data/lib/vulkan/generated/extensions/vk_khr_external_fence.rb +12 -0
  217. data/lib/vulkan/generated/extensions/vk_khr_external_fence_capabilities.rb +19 -0
  218. data/lib/vulkan/generated/extensions/vk_khr_external_fence_fd.rb +12 -0
  219. data/lib/vulkan/generated/extensions/vk_khr_external_fence_win32.rb +13 -0
  220. data/lib/vulkan/generated/extensions/vk_khr_external_memory.rb +15 -0
  221. data/lib/vulkan/generated/extensions/vk_khr_external_memory_capabilities.rb +26 -0
  222. data/lib/vulkan/generated/extensions/vk_khr_external_memory_fd.rb +13 -0
  223. data/lib/vulkan/generated/extensions/vk_khr_external_memory_win32.rb +14 -0
  224. data/lib/vulkan/generated/extensions/vk_khr_external_semaphore.rb +12 -0
  225. data/lib/vulkan/generated/extensions/vk_khr_external_semaphore_capabilities.rb +20 -0
  226. data/lib/vulkan/generated/extensions/vk_khr_external_semaphore_fd.rb +12 -0
  227. data/lib/vulkan/generated/extensions/vk_khr_external_semaphore_win32.rb +14 -0
  228. data/lib/vulkan/generated/extensions/vk_khr_get_display_properties2.rb +15 -0
  229. data/lib/vulkan/generated/extensions/vk_khr_get_memory_requirements2.rb +15 -0
  230. data/lib/vulkan/generated/extensions/vk_khr_get_physical_device_properties2.rb +19 -0
  231. data/lib/vulkan/generated/extensions/vk_khr_get_surface_capabilities2.rb +13 -0
  232. data/lib/vulkan/generated/extensions/vk_khr_image_format_list.rb +11 -0
  233. data/lib/vulkan/generated/extensions/vk_khr_incremental_present.rb +11 -0
  234. data/lib/vulkan/generated/extensions/vk_khr_maintenance1.rb +14 -0
  235. data/lib/vulkan/generated/extensions/vk_khr_maintenance2.rb +22 -0
  236. data/lib/vulkan/generated/extensions/vk_khr_maintenance3.rb +12 -0
  237. data/lib/vulkan/generated/extensions/vk_khr_mir_surface.rb +10 -0
  238. data/lib/vulkan/generated/extensions/vk_khr_multiview.rb +14 -0
  239. data/lib/vulkan/generated/extensions/vk_khr_push_descriptor.rb +13 -0
  240. data/lib/vulkan/generated/extensions/vk_khr_relaxed_block_layout.rb +10 -0
  241. data/lib/vulkan/generated/extensions/vk_khr_sampler_mirror_clamp_to_edge.rb +11 -0
  242. data/lib/vulkan/generated/extensions/vk_khr_sampler_ycbcr_conversion.rb +73 -0
  243. data/lib/vulkan/generated/extensions/vk_khr_shader_atomic_int64.rb +11 -0
  244. data/lib/vulkan/generated/extensions/vk_khr_shader_draw_parameters.rb +10 -0
  245. data/lib/vulkan/generated/extensions/vk_khr_shared_presentable_image.rb +14 -0
  246. data/lib/vulkan/generated/extensions/vk_khr_storage_buffer_storage_class.rb +10 -0
  247. data/lib/vulkan/generated/extensions/vk_khr_surface.rb +13 -0
  248. data/lib/vulkan/generated/extensions/vk_khr_swapchain.rb +24 -0
  249. data/lib/vulkan/generated/extensions/vk_khr_variable_pointers.rb +11 -0
  250. data/lib/vulkan/generated/extensions/vk_khr_vulkan_memory_model.rb +11 -0
  251. data/lib/vulkan/generated/extensions/vk_khr_wayland_surface.rb +11 -0
  252. data/lib/vulkan/generated/extensions/vk_khr_win32_keyed_mutex.rb +11 -0
  253. data/lib/vulkan/generated/extensions/vk_khr_win32_surface.rb +11 -0
  254. data/lib/vulkan/generated/extensions/vk_khr_xcb_surface.rb +11 -0
  255. data/lib/vulkan/generated/extensions/vk_khr_xlib_surface.rb +11 -0
  256. data/lib/vulkan/generated/extensions/vk_mesa_extension_244.rb +10 -0
  257. data/lib/vulkan/generated/extensions/vk_mvk_ios_surface.rb +11 -0
  258. data/lib/vulkan/generated/extensions/vk_mvk_macos_surface.rb +11 -0
  259. data/lib/vulkan/generated/extensions/vk_mvk_moltenvk.rb +10 -0
  260. data/lib/vulkan/generated/extensions/vk_nn_vi_surface.rb +11 -0
  261. data/lib/vulkan/generated/extensions/vk_nv_clip_space_w_scaling.rb +12 -0
  262. data/lib/vulkan/generated/extensions/vk_nv_compute_shader_derivatives.rb +11 -0
  263. data/lib/vulkan/generated/extensions/vk_nv_corner_sampled_image.rb +12 -0
  264. data/lib/vulkan/generated/extensions/vk_nv_dedicated_allocation.rb +13 -0
  265. data/lib/vulkan/generated/extensions/vk_nv_device_diagnostic_checkpoints.rb +12 -0
  266. data/lib/vulkan/generated/extensions/vk_nv_extension_101.rb +10 -0
  267. data/lib/vulkan/generated/extensions/vk_nv_extension_103.rb +10 -0
  268. data/lib/vulkan/generated/extensions/vk_nv_extension_104.rb +10 -0
  269. data/lib/vulkan/generated/extensions/vk_nv_extension_151.rb +10 -0
  270. data/lib/vulkan/generated/extensions/vk_nv_extension_152.rb +10 -0
  271. data/lib/vulkan/generated/extensions/vk_nv_extension_155.rb +10 -0
  272. data/lib/vulkan/generated/extensions/vk_nv_extension_164.rb +10 -0
  273. data/lib/vulkan/generated/extensions/vk_nv_extension_168.rb +10 -0
  274. data/lib/vulkan/generated/extensions/vk_nv_extension_241.rb +10 -0
  275. data/lib/vulkan/generated/extensions/vk_nv_extension_242.rb +10 -0
  276. data/lib/vulkan/generated/extensions/vk_nv_extension_245.rb +10 -0
  277. data/lib/vulkan/generated/extensions/vk_nv_extension_53.rb +10 -0
  278. data/lib/vulkan/generated/extensions/vk_nv_external_memory.rb +12 -0
  279. data/lib/vulkan/generated/extensions/vk_nv_external_memory_capabilities.rb +10 -0
  280. data/lib/vulkan/generated/extensions/vk_nv_external_memory_win32.rb +12 -0
  281. data/lib/vulkan/generated/extensions/vk_nv_fill_rectangle.rb +11 -0
  282. data/lib/vulkan/generated/extensions/vk_nv_fragment_coverage_to_color.rb +11 -0
  283. data/lib/vulkan/generated/extensions/vk_nv_fragment_shader_barycentric.rb +11 -0
  284. data/lib/vulkan/generated/extensions/vk_nv_framebuffer_mixed_samples.rb +11 -0
  285. data/lib/vulkan/generated/extensions/vk_nv_geometry_shader_passthrough.rb +10 -0
  286. data/lib/vulkan/generated/extensions/vk_nv_glsl_shader.rb +11 -0
  287. data/lib/vulkan/generated/extensions/vk_nv_mesh_shader.rb +16 -0
  288. data/lib/vulkan/generated/extensions/vk_nv_ray_tracing.rb +40 -0
  289. data/lib/vulkan/generated/extensions/vk_nv_representative_fragment_test.rb +12 -0
  290. data/lib/vulkan/generated/extensions/vk_nv_sample_mask_override_coverage.rb +10 -0
  291. data/lib/vulkan/generated/extensions/vk_nv_scissor_exclusive.rb +13 -0
  292. data/lib/vulkan/generated/extensions/vk_nv_shader_image_footprint.rb +11 -0
  293. data/lib/vulkan/generated/extensions/vk_nv_shader_subgroup_partitioned.rb +11 -0
  294. data/lib/vulkan/generated/extensions/vk_nv_shading_rate_image.rb +20 -0
  295. data/lib/vulkan/generated/extensions/vk_nv_viewport_array2.rb +10 -0
  296. data/lib/vulkan/generated/extensions/vk_nv_viewport_swizzle.rb +11 -0
  297. data/lib/vulkan/generated/extensions/vk_nv_win32_keyed_mutex.rb +11 -0
  298. data/lib/vulkan/generated/extensions/vk_nvx_device_generated_commands.rb +21 -0
  299. data/lib/vulkan/generated/extensions/vk_nvx_extension_30.rb +10 -0
  300. data/lib/vulkan/generated/extensions/vk_nvx_extension_31.rb +10 -0
  301. data/lib/vulkan/generated/extensions/vk_nvx_extension_48.rb +10 -0
  302. data/lib/vulkan/generated/extensions/vk_nvx_extension_52.rb +10 -0
  303. data/lib/vulkan/generated/extensions/vk_nvx_multiview_per_view_attributes.rb +13 -0
  304. data/lib/vulkan/generated/extensions/vk_qcom_extension_171.rb +10 -0
  305. data/lib/vulkan/generated/extensions/vk_qcom_extension_172.rb +10 -0
  306. data/lib/vulkan/generated/extensions/vk_qcom_extension_173.rb +10 -0
  307. data/lib/vulkan/generated/extensions/vk_qcom_extension_174.rb +10 -0
  308. data/lib/vulkan/generated/extensions.rb +251 -0
  309. data/lib/vulkan/generated/structs.rb +2600 -0
  310. data/lib/vulkan/generated/types.rb +348 -0
  311. data/lib/vulkan/generated/vk.xml +10127 -0
  312. data/lib/vulkan/generated.rb +77 -0
  313. data/lib/vulkan/image.rb +263 -0
  314. data/lib/vulkan/image_memory.rb +13 -0
  315. data/lib/vulkan/image_view.rb +46 -0
  316. data/lib/vulkan/instance.rb +183 -0
  317. data/lib/vulkan/logical_device.rb +165 -0
  318. data/lib/vulkan/memory.rb +171 -0
  319. data/lib/vulkan/mock/swapchain_surface_info.rb +42 -0
  320. data/lib/vulkan/mock.rb +5 -0
  321. data/lib/vulkan/physical_device.rb +162 -0
  322. data/lib/vulkan/pipeline.rb +294 -0
  323. data/lib/vulkan/platform.rb +34 -0
  324. data/lib/vulkan/queue.rb +94 -0
  325. data/lib/vulkan/queue_family.rb +27 -0
  326. data/lib/vulkan/render_pass/subpass.rb +80 -0
  327. data/lib/vulkan/render_pass.rb +71 -0
  328. data/lib/vulkan/sampler.rb +48 -0
  329. data/lib/vulkan/semaphore.rb +16 -0
  330. data/lib/vulkan/shader_stage.rb +33 -0
  331. data/lib/vulkan/surface.rb +10 -0
  332. data/lib/vulkan/swapchain.rb +87 -0
  333. data/lib/vulkan/swapchain_builder.rb +111 -0
  334. data/lib/vulkan/swapchain_surface_info.rb +54 -0
  335. data/lib/vulkan/version.rb +3 -0
  336. data/lib/vulkan/window_surface.rb +13 -0
  337. data/lib/vulkan-ruby.rb +1 -0
  338. data/lib/vulkan.rb +91 -0
  339. data/tasks/examples.rake +29 -0
  340. data/tasks/fetch.rake +9 -0
  341. data/tasks/generate/commands.rake +51 -0
  342. data/tasks/generate/enums.rake +43 -0
  343. data/tasks/generate/extensions.rake +35 -0
  344. data/tasks/generate/structs.rake +117 -0
  345. data/tasks/generate/types.rake +91 -0
  346. data/tasks/generate.rake +2 -0
  347. data/tasks/helpers.rb +59 -0
  348. data/tasks/shaders.rake +8 -0
  349. data/vulkan-ruby.gemspec +45 -0
  350. metadata +546 -0
@@ -0,0 +1,321 @@
1
+ # https://vulkan-tutorial.com/code/27_model_loading.cpp
2
+
3
+ require 'bundler/setup'
4
+ require 'simplecov'
5
+ require 'vulkan'
6
+ require 'sdl2_vulkan'
7
+ require 'cglm'
8
+ require 'chunky_png'
9
+ require 'oily_png'
10
+ require 'tiny_obj'
11
+
12
+ include CGLM
13
+ UniformBufferStruct = Vulkan.struct(['float model[16]', 'float view[16]', 'float proj[16]'])
14
+ def UniformBufferStruct.alignment; Mat4.alignment; end
15
+ $ubo = UniformBufferStruct.new(CGLM.alloc(UniformBufferStruct))
16
+ $model_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('model'))
17
+ $view_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('view'))
18
+ $projection_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('proj'))
19
+
20
+ obj = TinyOBJ.load(File.expand_path('models/viking_room.obj', __dir__))
21
+ NUM_INDICES = obj.num_indices
22
+ Vertex = Vulkan.struct(['float pos[3]', 'float color[3]', 'float texcoords[2]'])
23
+ IndexData = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT * NUM_INDICES)
24
+ VertexData = Fiddle::Pointer.malloc(Vertex.size * obj.num_distinct_vertices)
25
+ obj.fill_buffers index_type: :uint32,
26
+ index_stride: Fiddle::SIZEOF_INT,
27
+ vertex_stride: Vertex.size,
28
+ flip_v: true,
29
+ indices: IndexData,
30
+ positions: VertexData,
31
+ colors: VertexData + Vertex.offsetof('color'),
32
+ texcoords: VertexData + Vertex.offsetof('texcoords')
33
+
34
+ # Create a window that we plan to draw to
35
+ SDL2.init(SDL2::INIT_EVERYTHING)
36
+ window = SDL2::Window.create "test-vulkan", 0, 0, 640, 480, SDL2::Window::Flags::VULKAN |
37
+ SDL2::Window::Flags::RESIZABLE |
38
+ 0x00002000 # SDL2::Window::Flags::ALLOW_HIGHDPI
39
+
40
+ # Create a Vulkan instance
41
+ instance = Vulkan::Instance.new extensions: window.vk_instance_extensions
42
+
43
+ # Create a rendering surface
44
+ surface = instance.create_window_surface(window)
45
+
46
+ # Choose an adequate physical device
47
+ dev = instance.physical_devices.detect do |dev|
48
+ next false unless swapchain_surface_info = dev.swapchain_surface_info(surface)
49
+ builder = Vulkan::SwapchainBuilder.new(swapchain_surface_info)
50
+ dev.properties[:device_type] == :discrete_gpu &&
51
+ (builder.format rescue false) && (builder.presentation_mode rescue false)
52
+ end
53
+ raise 'could not find a suitable physical device' unless dev
54
+
55
+ # Find a queue family that supports graphics
56
+ graphics_queue_family = dev.queue_families.detect do |family|
57
+ family[:queue_count] > 0 && family.supports?(:graphics)
58
+ end
59
+ raise 'no graphics queue family available' unless graphics_queue_family
60
+
61
+ # Find a queue family that supports presentation to the rendering surface
62
+ presentation_queue_family = dev.queue_families.detect do |family|
63
+ family[:queue_count] > 0 && family.supports_presentation?(surface)
64
+ end
65
+ raise 'no graphics queue family available' unless presentation_queue_family
66
+
67
+ # Create a logical device along with the needed extensions and chosen queues
68
+ if graphics_queue_family == presentation_queue_family
69
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] }],
70
+ extensions: ['VK_KHR_swapchain']
71
+ presentation_queue = graphics_queue = device.queue_families[0][:queues][0]
72
+ else
73
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] },
74
+ { family: presentation_queue_family, priorities: [1.0] }],
75
+ extensions: ['VK_KHR_swapchain']
76
+ graphics_queue = device.queue_families[0][:queues][0]
77
+ presentation_queue = device.queue_families[1][:queues][0]
78
+ end
79
+
80
+ command_pool = device.create_command_pool queue_family: graphics_queue_family
81
+
82
+ # Populate the vertex buffer
83
+ staging_buffer = device.create_buffer size: VertexData.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
84
+ staging_buffer.map { |data| data[0, VertexData.size] = VertexData[0, VertexData.size] }
85
+ VertexBuffer = device.create_buffer size: VertexData.size,
86
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
87
+ properties: :device_local
88
+ vertex_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, VertexBuffer }
89
+
90
+ # Populate the index buffer
91
+ staging_buffer = device.create_buffer size: IndexData.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
92
+ staging_buffer.map { |data| data[0, IndexData.size] = IndexData[0, IndexData.size] }
93
+ IndexBuffer = device.create_buffer size: IndexData.size,
94
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
95
+ properties: :device_local
96
+ index_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, IndexBuffer }
97
+
98
+ # Submit both transfers and wait for them to complete
99
+ graphics_queue.submit([vertex_transfer_buffer, index_transfer_buffer])
100
+ # graphics_queue.wait_until_idle
101
+
102
+ UniformBuffers = []
103
+
104
+ png = ChunkyPNG::Image.from_file(File.expand_path('textures/viking_room.png', __dir__))
105
+ image_data = png.to_rgba_stream
106
+ image_data_buffer = device.create_buffer size: image_data.size,
107
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
108
+ properties: [:host_visible, :host_coherent]
109
+ image_data_buffer.map { |data| data[0, image_data.size] = image_data }
110
+ texture = device.create_image dimensions: 2,
111
+ width: png.width,
112
+ height: png.height,
113
+ depth: 1,
114
+ mip_levels: 1,
115
+ array_layers: 1,
116
+ format: :r8g8b8a8_unorm,
117
+ tiling: :optimal,
118
+ initial_layout: :undefined,
119
+ usage: [:transfer_dst, :sampled],
120
+ sharing: :exclusive,
121
+ samples: 1
122
+ texture.transition_layout command_pool, graphics_queue, to: :transfer_dst_optimal
123
+ texture.copy_from_buffer command_pool, graphics_queue, buffer: image_data_buffer, width: png.width, height: png.height
124
+ graphics_queue.wait_until_idle
125
+ texture.transition_layout command_pool, graphics_queue, to: :shader_ro_optimal
126
+ texture_view = texture.create_view
127
+ sampler = device.create_sampler
128
+
129
+ shader_stages = [
130
+ device.create_shader_stage(file_path: File.expand_path('./shaders/model_loading.vert.spv', __dir__),
131
+ stage: Vulkan::VK_SHADER_STAGE_VERTEX_BIT),
132
+ device.create_shader_stage(file_path: File.expand_path('./shaders/model_loading.frag.spv', __dir__),
133
+ stage: Vulkan::VK_SHADER_STAGE_FRAGMENT_BIT)
134
+ ]
135
+
136
+ rebuild_swap_chain = proc do
137
+ # Create a swapchain for image presentation
138
+ $swapchain = device.create_swapchain surface: surface,
139
+ surface_width: window.vk_drawable_size[0],
140
+ surface_height: window.vk_drawable_size[1]
141
+
142
+ # Create render pass with one subpass
143
+ render_pass = device.create_renderpass
144
+ depth_format = device.physical_device.detect_supported_format(
145
+ :d32_sfloat, :d32_sfloat_s8_uint, :d24_unorm_s8_uint,
146
+ usage: :depth_stencil_attachment,
147
+ tiling: :optimal
148
+ )
149
+ depth_attachment_index = render_pass.add_attachment format: depth_format,
150
+ samples: 1,
151
+ load_op: :clear,
152
+ store_op: :dont_care,
153
+ stencil_load_op: :dont_care,
154
+ stencil_store_op: :dont_care,
155
+ initial_layout: nil,
156
+ final_layout: :depth_stencil_attachment
157
+ subpass = render_pass.add_subpass
158
+ subpass.add_color_attachment_ref index: render_pass.add_attachment(format: $swapchain.format)
159
+ subpass.set_depth_stencil_attachment_ref index: depth_attachment_index
160
+ render_pass.commit
161
+
162
+ depth_image = device.create_image dimensions: 2,
163
+ width: $swapchain.width,
164
+ height: $swapchain.height,
165
+ depth: 1,
166
+ mip_levels: 1,
167
+ array_layers: 1,
168
+ format: depth_format,
169
+ tiling: :optimal,
170
+ initial_layout: :undefined,
171
+ usage: [:depth_stencil_attachment],
172
+ sharing: :exclusive,
173
+ samples: 1
174
+ depth_image_view = depth_image.create_view aspects: :depth
175
+ depth_image.transition_layout command_pool, graphics_queue, to: :depth_stencil_attachment_optimal,
176
+ aspects: :depth
177
+
178
+ # Create a framebuffer for each image in the swap chain, and associate each with the depth image
179
+ framebuffers = $swapchain.image_views.map do |swapchain_image_view|
180
+ device.create_framebuffer(width: $swapchain.width,
181
+ height: $swapchain.height,
182
+ render_pass: render_pass,
183
+ attachments: [depth_image_view,
184
+ swapchain_image_view])
185
+ end
186
+
187
+ # Create graphic pipeline
188
+ pipeline = device.create_pipeline(viewport: { width: $swapchain.width, height: $swapchain.height })
189
+ pipeline.depth
190
+ pipeline.add_binding_description binding: 0,
191
+ stride: Vertex.size,
192
+ input_rate: Vulkan::VK_VERTEX_INPUT_RATE_VERTEX
193
+
194
+ pipeline.add_attribute_description binding: 0,
195
+ location: 0,
196
+ format: :r32g32b32_sfloat,
197
+ offset: 0
198
+
199
+ pipeline.add_attribute_description binding: 0,
200
+ location: 1,
201
+ format: :r32g32b32_sfloat,
202
+ offset: Fiddle::SIZEOF_FLOAT * 3
203
+
204
+ pipeline.add_attribute_description binding: 0,
205
+ location: 2,
206
+ format: :r32g32_sfloat,
207
+ offset: Fiddle::SIZEOF_FLOAT * 6
208
+
209
+ # Create a uniform buffer for each image in the swapchain, so that we don't
210
+ # modify a buffer for a frame still in-flight
211
+ UniformBuffers.clear
212
+ $swapchain.size.times do |i|
213
+ UniformBuffers[i] = device.create_buffer size: UniformBufferStruct.size,
214
+ usage: Vulkan::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
215
+ properties: [:host_visible, :host_coherent]
216
+ end
217
+ descriptor_set_pool = device.create_descriptor_set_pool pool_sizes: [
218
+ {type: :uniform_buffer, count: $swapchain.size},
219
+ {type: :combined_image_sampler, count: $swapchain.size}
220
+ ],
221
+ max_sets: $swapchain.size
222
+ descriptor_set_layout = pipeline.add_descriptor_set_layout descriptors: [{
223
+ binding: 0,
224
+ type: :uniform_buffer,
225
+ stages: [:vertex]
226
+ }, {
227
+ binding: 1,
228
+ type: :combined_image_sampler,
229
+ stages: [:fragment]
230
+ }]
231
+ descriptor_sets = descriptor_set_pool.alloc(layouts: [descriptor_set_layout] * $swapchain.size)
232
+ descriptor_sets.each_with_index do |set, i|
233
+ set[0].set_buffer UniformBuffers[i]
234
+ set[1].set_image_view_and_sampler texture_view, sampler
235
+ set.commit
236
+ end
237
+
238
+ shader_stages.each { |stage| pipeline.add_shader_stage(stage) }
239
+ pipeline.commit(render_pass)
240
+
241
+ $command_buffers = command_pool.create_command_buffers(framebuffers.size) do |cmd, index|
242
+ cmd.render_pass(render_pass, framebuffer: framebuffers[index]) do
243
+ cmd.bind_pipeline(:graphics, pipeline)
244
+ cmd.bind_vertex_buffer(VertexBuffer)
245
+ cmd.bind_index_buffer(IndexBuffer, type: :uint32)
246
+ cmd.bind_descriptor_set(:graphics, descriptor_sets[index], pipeline_layout: pipeline.layout)
247
+ cmd.draw_indexed(NUM_INDICES, 1, 0, 0, 0)
248
+ end
249
+ end
250
+ end
251
+
252
+ rebuild_swap_chain.call
253
+
254
+ MAX_FRAMES_IN_FLIGHT = 2
255
+ image_available_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
256
+ render_finished_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
257
+ in_flight_fences = MAX_FRAMES_IN_FLIGHT.times.map { device.create_fence signaled: true }
258
+ current_frame = 0
259
+ frame_counter = 0
260
+ start_time = Time.now
261
+ done = false
262
+
263
+ Mat4.look_at Vec3.new([2, 2, 2]), Vec3.zero, Vec3.new([0, 0, 1]), $view_matrix
264
+ Mat4.perspective $projection_matrix, fovy: 45.to_radians,
265
+ aspect: $swapchain.width.to_f / $swapchain.height.to_f,
266
+ near: 0.1,
267
+ far: 10
268
+ # Convert OpenGL projection matrix into Vulkan projection matrix
269
+ # (e.g. NDC from z=-1..1 to z=0..1, and flip y)
270
+ $projection_matrix.mul_mat4 Mat4.new([Vec4.new([1.0, 0.0, 0.0, 0.0]),
271
+ Vec4.new([0.0, -1.0, 0.0, 0.0]),
272
+ Vec4.new([0.0, 0.0, 0.5, -0.5]),
273
+ Vec4.new([0.0, 0.0, 0.0, 1.0])]),
274
+ $projection_matrix
275
+ UniformBuffers.each { |b| b.map { |data| data[0, UniformBufferStruct.size] = $ubo[0, UniformBufferStruct.size] } }
276
+
277
+ # Begin main event loop & drawing
278
+ until done
279
+ frame_counter += 1
280
+ break if ENV['MAX_FRAMES'].to_i == frame_counter
281
+ # dump some FPS infos
282
+ uptime = ENV['TIME_STEP'] ? ENV['TIME_STEP'].to_f * frame_counter : Time.now - start_time
283
+ if frame_counter % 3000 == 0
284
+ fps = frame_counter / uptime
285
+ p ['fps: ', fps, 'frame-time (ms): ', 1000.0 / fps]
286
+ end
287
+ while event = SDL2::Event.poll
288
+ case event
289
+ when SDL2::Event::Quit, SDL2::Event::KeyDown then done = true
290
+ when SDL2::Event::Window::RESIZED then rebuild_swap_chain.call
291
+ end
292
+ end
293
+
294
+ begin
295
+ in_flight_fences[current_frame].wait
296
+ image_index = $swapchain.next_image_index(semaphore: image_available_semaphores[current_frame])
297
+ UniformBuffers[image_index].map do |data|
298
+ Mat4.identity $model_matrix
299
+ $model_matrix.rotate! Vec3.new([0, 0, 1]), uptime * 0.25 * 90.to_radians
300
+ data[0, Mat4.size] = $model_matrix.addr[0, Mat4.size]
301
+ end
302
+ in_flight_fences[current_frame].reset
303
+ graphics_queue.submit([$command_buffers[image_index]],
304
+ wait_semaphores: [image_available_semaphores[current_frame]],
305
+ wait_stages: [Vulkan::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
306
+ signal_semaphores: [render_finished_semaphores[current_frame]],
307
+ fence: in_flight_fences[current_frame])
308
+ presentation_queue.present(swapchains: [$swapchain],
309
+ image_indices: [image_index],
310
+ wait_semaphores: [render_finished_semaphores[current_frame]])
311
+ current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT
312
+ rescue Vulkan::Error
313
+ case $!.code
314
+ when Vulkan::VK_ERROR_OUT_OF_DATE_KHR, Vulkan::VK_SUBOPTIMAL_KHR
315
+ rebuild_swap_chain.call
316
+ else raise
317
+ end
318
+ end
319
+ end
320
+
321
+ in_flight_fences.each { |fence| fence.wait_and_reset }
@@ -0,0 +1,329 @@
1
+ # https://vulkan-tutorial.com/code/28_mipmapping.cpp
2
+
3
+ require 'bundler/setup'
4
+ require 'simplecov'
5
+ require 'vulkan'
6
+ require 'sdl2_vulkan'
7
+ require 'cglm'
8
+ require 'chunky_png'
9
+ require 'oily_png'
10
+ require 'tiny_obj'
11
+
12
+ include CGLM
13
+ UniformBufferStruct = Vulkan.struct(['float model[16]', 'float view[16]', 'float proj[16]'])
14
+ def UniformBufferStruct.alignment; Mat4.alignment; end
15
+ $ubo = UniformBufferStruct.new(CGLM.alloc(UniformBufferStruct))
16
+ $model_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('model'))
17
+ $view_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('view'))
18
+ $projection_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('proj'))
19
+
20
+ obj = TinyOBJ.load(File.expand_path('models/viking_room.obj', __dir__))
21
+ NUM_INDICES = obj.num_indices
22
+ Vertex = Vulkan.struct(['float pos[3]', 'float color[3]', 'float texcoords[2]'])
23
+ IndexData = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT * NUM_INDICES)
24
+ VertexData = Fiddle::Pointer.malloc(Vertex.size * obj.num_distinct_vertices)
25
+ obj.fill_buffers index_type: :uint32,
26
+ index_stride: Fiddle::SIZEOF_INT,
27
+ vertex_stride: Vertex.size,
28
+ flip_v: true,
29
+ indices: IndexData,
30
+ positions: VertexData,
31
+ colors: VertexData + Vertex.offsetof('color'),
32
+ texcoords: VertexData + Vertex.offsetof('texcoords')
33
+
34
+ # Create a window that we plan to draw to
35
+ SDL2.init(SDL2::INIT_EVERYTHING)
36
+ window = SDL2::Window.create "test-vulkan", 0, 0, 640, 480, SDL2::Window::Flags::VULKAN |
37
+ SDL2::Window::Flags::RESIZABLE |
38
+ 0x00002000 # SDL2::Window::Flags::ALLOW_HIGHDPI
39
+
40
+ # Create a Vulkan instance
41
+ instance = Vulkan::Instance.new extensions: window.vk_instance_extensions
42
+
43
+ # Create a rendering surface
44
+ surface = instance.create_window_surface(window)
45
+
46
+ # Choose an adequate physical device
47
+ dev = instance.physical_devices.detect do |dev|
48
+ next false unless swapchain_surface_info = dev.swapchain_surface_info(surface)
49
+ builder = Vulkan::SwapchainBuilder.new(swapchain_surface_info)
50
+ dev.properties[:device_type] == :discrete_gpu &&
51
+ (builder.format rescue false) && (builder.presentation_mode rescue false)
52
+ end
53
+ raise 'could not find a suitable physical device' unless dev
54
+
55
+ # Find a queue family that supports graphics
56
+ graphics_queue_family = dev.queue_families.detect do |family|
57
+ family[:queue_count] > 0 && family.supports?(:graphics)
58
+ end
59
+ raise 'no graphics queue family available' unless graphics_queue_family
60
+
61
+ # Find a queue family that supports presentation to the rendering surface
62
+ presentation_queue_family = dev.queue_families.detect do |family|
63
+ family[:queue_count] > 0 && family.supports_presentation?(surface)
64
+ end
65
+ raise 'no graphics queue family available' unless presentation_queue_family
66
+
67
+ # Create a logical device along with the needed extensions and chosen queues
68
+ if graphics_queue_family == presentation_queue_family
69
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] }],
70
+ extensions: ['VK_KHR_swapchain']
71
+ presentation_queue = graphics_queue = device.queue_families[0][:queues][0]
72
+ else
73
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] },
74
+ { family: presentation_queue_family, priorities: [1.0] }],
75
+ extensions: ['VK_KHR_swapchain']
76
+ graphics_queue = device.queue_families[0][:queues][0]
77
+ presentation_queue = device.queue_families[1][:queues][0]
78
+ end
79
+
80
+ command_pool = device.create_command_pool queue_family: graphics_queue_family
81
+
82
+ # Populate the vertex buffer
83
+ staging_buffer = device.create_buffer size: VertexData.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
84
+ staging_buffer.map { |data| data[0, VertexData.size] = VertexData[0, VertexData.size] }
85
+ VertexBuffer = device.create_buffer size: VertexData.size,
86
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
87
+ properties: :device_local
88
+ vertex_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, VertexBuffer }
89
+
90
+ # Populate the index buffer
91
+ staging_buffer = device.create_buffer size: IndexData.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
92
+ staging_buffer.map { |data| data[0, IndexData.size] = IndexData[0, IndexData.size] }
93
+ IndexBuffer = device.create_buffer size: IndexData.size,
94
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
95
+ properties: :device_local
96
+ index_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, IndexBuffer }
97
+
98
+ # Submit both transfers and wait for them to complete
99
+ graphics_queue.submit([vertex_transfer_buffer, index_transfer_buffer])
100
+ # graphics_queue.wait_until_idle
101
+
102
+ UniformBuffers = []
103
+
104
+ png = ChunkyPNG::Image.from_file(File.expand_path('textures/viking_room.png', __dir__))
105
+ num_mip_levels = Vulkan.num_mip_levels(png.width, png.height)
106
+ texture = device.create_image dimensions: 2,
107
+ width: png.width,
108
+ height: png.height,
109
+ depth: 1,
110
+ mip_levels: num_mip_levels,
111
+ array_layers: 1,
112
+ format: :r8g8b8a8_unorm,
113
+ tiling: :optimal,
114
+ initial_layout: :undefined,
115
+ usage: [:transfer_dst, :sampled],
116
+ sharing: :exclusive,
117
+ samples: 1
118
+ texture.transition_layout command_pool, graphics_queue, to: :transfer_dst_optimal
119
+ num_mip_levels.times do |mip_level|
120
+ image_data = png.to_rgba_stream
121
+ image_data_buffer = device.create_buffer size: image_data.size,
122
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
123
+ properties: [:host_visible, :host_coherent]
124
+ image_data_buffer.map { |data| data[0, image_data.size] = image_data }
125
+ texture.copy_from_buffer command_pool, graphics_queue, buffer: image_data_buffer,
126
+ width: png.width,
127
+ height: png.height,
128
+ mip_level: mip_level
129
+ png.resample_bilinear! png.width == 1 ? png.width : png.width / 2,
130
+ png.height == 1 ? png.height : png.height / 2
131
+ end
132
+ graphics_queue.wait_until_idle
133
+ texture.transition_layout command_pool, graphics_queue, to: :shader_ro_optimal
134
+ texture_view = texture.create_view
135
+ sampler = device.create_sampler max_lod: num_mip_levels#, min_lod: num_mip_levels / 2
136
+
137
+ shader_stages = [
138
+ device.create_shader_stage(file_path: File.expand_path('./shaders/model_loading.vert.spv', __dir__),
139
+ stage: Vulkan::VK_SHADER_STAGE_VERTEX_BIT),
140
+ device.create_shader_stage(file_path: File.expand_path('./shaders/model_loading.frag.spv', __dir__),
141
+ stage: Vulkan::VK_SHADER_STAGE_FRAGMENT_BIT)
142
+ ]
143
+
144
+ rebuild_swap_chain = proc do
145
+ # Create a swapchain for image presentation
146
+ $swapchain = device.create_swapchain surface: surface,
147
+ surface_width: window.vk_drawable_size[0],
148
+ surface_height: window.vk_drawable_size[1]
149
+
150
+ # Create render pass with one subpass
151
+ render_pass = device.create_renderpass
152
+ depth_format = device.physical_device.detect_supported_format(
153
+ :d32_sfloat, :d32_sfloat_s8_uint, :d24_unorm_s8_uint,
154
+ usage: :depth_stencil_attachment,
155
+ tiling: :optimal
156
+ )
157
+ depth_attachment_index = render_pass.add_attachment format: depth_format,
158
+ samples: 1,
159
+ load_op: :clear,
160
+ store_op: :dont_care,
161
+ stencil_load_op: :dont_care,
162
+ stencil_store_op: :dont_care,
163
+ initial_layout: nil,
164
+ final_layout: :depth_stencil_attachment
165
+ subpass = render_pass.add_subpass
166
+ subpass.add_color_attachment_ref index: render_pass.add_attachment(format: $swapchain.format)
167
+ subpass.set_depth_stencil_attachment_ref index: depth_attachment_index
168
+ render_pass.commit
169
+
170
+ depth_image = device.create_image dimensions: 2,
171
+ width: $swapchain.width,
172
+ height: $swapchain.height,
173
+ depth: 1,
174
+ mip_levels: 1,
175
+ array_layers: 1,
176
+ format: depth_format,
177
+ tiling: :optimal,
178
+ initial_layout: :undefined,
179
+ usage: [:depth_stencil_attachment],
180
+ sharing: :exclusive,
181
+ samples: 1
182
+ depth_image_view = depth_image.create_view aspects: :depth
183
+ depth_image.transition_layout command_pool, graphics_queue, to: :depth_stencil_attachment_optimal,
184
+ aspects: :depth
185
+
186
+ # Create a framebuffer for each image in the swap chain, and associate each with the depth image
187
+ framebuffers = $swapchain.image_views.map do |swapchain_image_view|
188
+ device.create_framebuffer(width: $swapchain.width,
189
+ height: $swapchain.height,
190
+ render_pass: render_pass,
191
+ attachments: [depth_image_view,
192
+ swapchain_image_view])
193
+ end
194
+
195
+ # Create graphic pipeline
196
+ pipeline = device.create_pipeline(viewport: { width: $swapchain.width, height: $swapchain.height })
197
+ pipeline.depth
198
+ pipeline.add_binding_description binding: 0,
199
+ stride: Vertex.size,
200
+ input_rate: Vulkan::VK_VERTEX_INPUT_RATE_VERTEX
201
+
202
+ pipeline.add_attribute_description binding: 0,
203
+ location: 0,
204
+ format: :r32g32b32_sfloat,
205
+ offset: 0
206
+
207
+ pipeline.add_attribute_description binding: 0,
208
+ location: 1,
209
+ format: :r32g32b32_sfloat,
210
+ offset: Fiddle::SIZEOF_FLOAT * 3
211
+
212
+ pipeline.add_attribute_description binding: 0,
213
+ location: 2,
214
+ format: :r32g32_sfloat,
215
+ offset: Fiddle::SIZEOF_FLOAT * 6
216
+
217
+ # Create a uniform buffer for each image in the swapchain, so that we don't
218
+ # modify a buffer for a frame still in-flight
219
+ UniformBuffers.clear
220
+ $swapchain.size.times do |i|
221
+ UniformBuffers[i] = device.create_buffer size: UniformBufferStruct.size,
222
+ usage: Vulkan::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
223
+ properties: [:host_visible, :host_coherent]
224
+ end
225
+ descriptor_set_pool = device.create_descriptor_set_pool pool_sizes: [
226
+ {type: :uniform_buffer, count: $swapchain.size},
227
+ {type: :combined_image_sampler, count: $swapchain.size}
228
+ ],
229
+ max_sets: $swapchain.size
230
+ descriptor_set_layout = pipeline.add_descriptor_set_layout descriptors: [{
231
+ binding: 0,
232
+ type: :uniform_buffer,
233
+ stages: [:vertex]
234
+ }, {
235
+ binding: 1,
236
+ type: :combined_image_sampler,
237
+ stages: [:fragment]
238
+ }]
239
+ descriptor_sets = descriptor_set_pool.alloc(layouts: [descriptor_set_layout] * $swapchain.size)
240
+ descriptor_sets.each_with_index do |set, i|
241
+ set[0].set_buffer UniformBuffers[i]
242
+ set[1].set_image_view_and_sampler texture_view, sampler
243
+ set.commit
244
+ end
245
+
246
+ shader_stages.each { |stage| pipeline.add_shader_stage(stage) }
247
+ pipeline.commit(render_pass)
248
+
249
+ $command_buffers = command_pool.create_command_buffers(framebuffers.size) do |cmd, index|
250
+ cmd.render_pass(render_pass, framebuffer: framebuffers[index]) do
251
+ cmd.bind_pipeline(:graphics, pipeline)
252
+ cmd.bind_vertex_buffer(VertexBuffer)
253
+ cmd.bind_index_buffer(IndexBuffer, type: :uint32)
254
+ cmd.bind_descriptor_set(:graphics, descriptor_sets[index], pipeline_layout: pipeline.layout)
255
+ cmd.draw_indexed(NUM_INDICES, 1, 0, 0, 0)
256
+ end
257
+ end
258
+ end
259
+
260
+ rebuild_swap_chain.call
261
+
262
+ MAX_FRAMES_IN_FLIGHT = 2
263
+ image_available_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
264
+ render_finished_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
265
+ in_flight_fences = MAX_FRAMES_IN_FLIGHT.times.map { device.create_fence signaled: true }
266
+ current_frame = 0
267
+ frame_counter = 0
268
+ start_time = Time.now
269
+ done = false
270
+
271
+ Mat4.look_at Vec3.new([2, 2, 2]), Vec3.zero, Vec3.new([0, 0, 1]), $view_matrix
272
+ Mat4.perspective $projection_matrix, fovy: 45.to_radians,
273
+ aspect: $swapchain.width.to_f / $swapchain.height.to_f,
274
+ near: 0.1,
275
+ far: 10
276
+ # Convert OpenGL projection matrix into Vulkan projection matrix
277
+ # (e.g. NDC from z=-1..1 to z=0..1, and flip y)
278
+ $projection_matrix.mul_mat4 Mat4.new([Vec4.new([1.0, 0.0, 0.0, 0.0]),
279
+ Vec4.new([0.0, -1.0, 0.0, 0.0]),
280
+ Vec4.new([0.0, 0.0, 0.5, -0.5]),
281
+ Vec4.new([0.0, 0.0, 0.0, 1.0])]),
282
+ $projection_matrix
283
+ UniformBuffers.each { |b| b.map { |data| data[0, UniformBufferStruct.size] = $ubo[0, UniformBufferStruct.size] } }
284
+
285
+ # Begin main event loop & drawing
286
+ until done
287
+ frame_counter += 1
288
+ break if ENV['MAX_FRAMES'].to_i == frame_counter
289
+ # dump some FPS infos
290
+ uptime = ENV['TIME_STEP'] ? ENV['TIME_STEP'].to_f * frame_counter : Time.now - start_time
291
+ if frame_counter % 3000 == 0
292
+ fps = frame_counter / uptime
293
+ p ['fps: ', fps, 'frame-time (ms): ', 1000.0 / fps]
294
+ end
295
+ while event = SDL2::Event.poll
296
+ case event
297
+ when SDL2::Event::Quit, SDL2::Event::KeyDown then done = true
298
+ when SDL2::Event::Window::RESIZED then rebuild_swap_chain.call
299
+ end
300
+ end
301
+
302
+ begin
303
+ in_flight_fences[current_frame].wait
304
+ image_index = $swapchain.next_image_index(semaphore: image_available_semaphores[current_frame])
305
+ UniformBuffers[image_index].map do |data|
306
+ Mat4.identity $model_matrix
307
+ $model_matrix.rotate! Vec3.new([0, 0, 1]), uptime * 0.25 * 90.to_radians
308
+ data[0, Mat4.size] = $model_matrix.addr[0, Mat4.size]
309
+ end
310
+ in_flight_fences[current_frame].reset
311
+ graphics_queue.submit([$command_buffers[image_index]],
312
+ wait_semaphores: [image_available_semaphores[current_frame]],
313
+ wait_stages: [Vulkan::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
314
+ signal_semaphores: [render_finished_semaphores[current_frame]],
315
+ fence: in_flight_fences[current_frame])
316
+ presentation_queue.present(swapchains: [$swapchain],
317
+ image_indices: [image_index],
318
+ wait_semaphores: [render_finished_semaphores[current_frame]])
319
+ current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT
320
+ rescue Vulkan::Error
321
+ case $!.code
322
+ when Vulkan::VK_ERROR_OUT_OF_DATE_KHR, Vulkan::VK_SUBOPTIMAL_KHR
323
+ rebuild_swap_chain.call
324
+ else raise
325
+ end
326
+ end
327
+ end
328
+
329
+ in_flight_fences.each { |fence| fence.wait_and_reset }