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,275 @@
1
+ # https://vulkan-tutorial.com/code/25_texture_mapping.cpp
2
+
3
+ require 'bundler/setup'
4
+ require 'simplecov'
5
+ require 'vulkan'
6
+ require 'sdl2_vulkan'
7
+ require 'cglm'
8
+ require 'chunky_png'
9
+
10
+ include CGLM
11
+ UniformBufferStruct = Vulkan.struct(['float model[16]', 'float view[16]', 'float proj[16]'])
12
+ def UniformBufferStruct.alignment; Mat4.alignment; end
13
+ $ubo = UniformBufferStruct.new(CGLM.alloc(UniformBufferStruct))
14
+ $model_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('model'))
15
+ $view_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('view'))
16
+ $projection_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('proj'))
17
+
18
+ Vertex = Vulkan.struct(['float pos[2]', 'float color[3]', 'float texcoords[2]'])
19
+ VertexData = Vulkan.struct('vertices[4]' => Vertex).malloc
20
+ VertexData.vertices[0].pos = [-0.5, -0.5]; VertexData.vertices[0].color = [1, 0, 0]; VertexData.vertices[0].texcoords = [1, 0]
21
+ VertexData.vertices[1].pos = [ 0.5, -0.5]; VertexData.vertices[1].color = [0, 1, 0]; VertexData.vertices[1].texcoords = [0, 0]
22
+ VertexData.vertices[2].pos = [ 0.5, 0.5]; VertexData.vertices[2].color = [0, 0, 1]; VertexData.vertices[2].texcoords = [0, 1]
23
+ VertexData.vertices[3].pos = [-0.5, 0.5]; VertexData.vertices[3].color = [1, 1, 1]; VertexData.vertices[3].texcoords = [1, 1]
24
+
25
+ IndexData = Vulkan.struct(['uint16_t indices[6]']).malloc
26
+ IndexData.indices = [0, 1, 2, 2, 3, 0]
27
+
28
+ # Create a window that we plan to draw to
29
+ SDL2.init(SDL2::INIT_EVERYTHING)
30
+ window = SDL2::Window.create "test-vulkan", 0, 0, 640, 480, SDL2::Window::Flags::VULKAN |
31
+ SDL2::Window::Flags::RESIZABLE |
32
+ 0x00002000 # SDL2::Window::Flags::ALLOW_HIGHDPI
33
+
34
+ # Create a Vulkan instance
35
+ instance = Vulkan::Instance.new extensions: window.vk_instance_extensions
36
+
37
+ # Create a rendering surface
38
+ surface = instance.create_window_surface(window)
39
+
40
+ # Choose an adequate physical device
41
+ dev = instance.physical_devices.detect do |dev|
42
+ next false unless swapchain_surface_info = dev.swapchain_surface_info(surface)
43
+ builder = Vulkan::SwapchainBuilder.new(swapchain_surface_info)
44
+ dev.properties[:device_type] == :discrete_gpu &&
45
+ (builder.format rescue false) && (builder.presentation_mode rescue false)
46
+ end
47
+ raise 'could not find a suitable physical device' unless dev
48
+
49
+ # Find a queue family that supports graphics
50
+ graphics_queue_family = dev.queue_families.detect do |family|
51
+ family[:queue_count] > 0 && family.supports?(:graphics)
52
+ end
53
+ raise 'no graphics queue family available' unless graphics_queue_family
54
+
55
+ # Find a queue family that supports presentation to the rendering surface
56
+ presentation_queue_family = dev.queue_families.detect do |family|
57
+ family[:queue_count] > 0 && family.supports_presentation?(surface)
58
+ end
59
+ raise 'no graphics queue family available' unless presentation_queue_family
60
+
61
+ # Create a logical device along with the needed extensions and chosen queues
62
+ if graphics_queue_family == presentation_queue_family
63
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] }],
64
+ extensions: ['VK_KHR_swapchain']
65
+ presentation_queue = graphics_queue = device.queue_families[0][:queues][0]
66
+ else
67
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] },
68
+ { family: presentation_queue_family, priorities: [1.0] }],
69
+ extensions: ['VK_KHR_swapchain']
70
+ graphics_queue = device.queue_families[0][:queues][0]
71
+ presentation_queue = device.queue_families[1][:queues][0]
72
+ end
73
+
74
+ command_pool = device.create_command_pool queue_family: graphics_queue_family
75
+
76
+ # Populate the vertex buffer
77
+ staging_buffer = device.create_buffer size: VertexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
78
+ staging_buffer.map { |data| data[0, VertexData.class.size] = VertexData[0, VertexData.class.size] }
79
+ VertexBuffer = device.create_buffer size: VertexData.class.size,
80
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
81
+ properties: :device_local
82
+ vertex_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, VertexBuffer }
83
+
84
+ # Populate the index buffer
85
+ staging_buffer = device.create_buffer size: IndexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
86
+ staging_buffer.map { |data| data[0, IndexData.class.size] = IndexData[0, IndexData.class.size] }
87
+ IndexBuffer = device.create_buffer size: IndexData.class.size,
88
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
89
+ properties: :device_local
90
+ index_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, IndexBuffer }
91
+
92
+ # Submit both transfers and wait for them to complete
93
+ graphics_queue.submit([vertex_transfer_buffer, index_transfer_buffer])
94
+ # graphics_queue.wait_until_idle
95
+
96
+ UniformBuffers = []
97
+
98
+ png = ChunkyPNG::Image.from_file(File.expand_path('textures/texture.png', __dir__))
99
+ image_data = png.to_rgba_stream
100
+ image_data_buffer = device.create_buffer size: image_data.size,
101
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
102
+ properties: [:host_visible, :host_coherent]
103
+ image_data_buffer.map { |data| data[0, image_data.size] = image_data }
104
+ texture = device.create_image dimensions: 2,
105
+ width: png.width,
106
+ height: png.height,
107
+ depth: 1,
108
+ mip_levels: 1,
109
+ array_layers: 1,
110
+ format: :r8g8b8a8_unorm,
111
+ tiling: :optimal,
112
+ initial_layout: :undefined,
113
+ usage: [:transfer_dst, :sampled],
114
+ sharing: :exclusive,
115
+ samples: 1
116
+ texture.transition_layout command_pool, graphics_queue, to: :transfer_dst_optimal
117
+ texture.copy_from_buffer command_pool, graphics_queue, buffer: image_data_buffer, width: png.width, height: png.height
118
+ graphics_queue.wait_until_idle
119
+ texture.transition_layout command_pool, graphics_queue, to: :shader_ro_optimal
120
+ texture_view = texture.create_view
121
+ sampler = device.create_sampler
122
+
123
+ shader_stages = [
124
+ device.create_shader_stage(file_path: File.expand_path('./shaders/textures.vert.spv', __dir__),
125
+ stage: Vulkan::VK_SHADER_STAGE_VERTEX_BIT),
126
+ device.create_shader_stage(file_path: File.expand_path('./shaders/textures.frag.spv', __dir__),
127
+ stage: Vulkan::VK_SHADER_STAGE_FRAGMENT_BIT)
128
+ ]
129
+
130
+ rebuild_swap_chain = proc do
131
+ # Create a swapchain for image presentation
132
+ $swapchain = device.create_swapchain surface: surface,
133
+ surface_width: window.vk_drawable_size[0],
134
+ surface_height: window.vk_drawable_size[1]
135
+
136
+ # Create render pass with one subpass
137
+ render_pass = device.create_renderpass
138
+ subpass = render_pass.add_subpass
139
+ subpass.add_color_attachment_ref index: render_pass.add_attachment(format: $swapchain.format),
140
+ layout: :color
141
+ render_pass.commit
142
+
143
+ # Create a framebuffer for each image in the swap chain
144
+ framebuffers = $swapchain.image_views.map do |swapchain_image_view|
145
+ device.create_framebuffer(width: $swapchain.width,
146
+ height: $swapchain.height,
147
+ render_pass: render_pass,
148
+ attachments: [swapchain_image_view])
149
+ end
150
+
151
+ # Create graphic pipeline
152
+ pipeline = device.create_pipeline(viewport: { width: $swapchain.width, height: $swapchain.height })
153
+ pipeline.add_binding_description binding: 0,
154
+ stride: Vertex.size,
155
+ input_rate: Vulkan::VK_VERTEX_INPUT_RATE_VERTEX
156
+
157
+ pipeline.add_attribute_description binding: 0,
158
+ location: 0,
159
+ format: :r32g32_sfloat,
160
+ offset: Vertex.offsetof('pos')
161
+
162
+ pipeline.add_attribute_description binding: 0,
163
+ location: 1,
164
+ format: :r32g32b32_sfloat,
165
+ offset: Vertex.offsetof('color')
166
+
167
+ pipeline.add_attribute_description binding: 0,
168
+ location: 2,
169
+ format: :r32g32_sfloat,
170
+ offset: Vertex.offsetof('texcoords')
171
+
172
+ # Create a uniform buffer for each image in the swapchain, so that we don't
173
+ # modify a buffer for a frame still in-flight
174
+ UniformBuffers.clear
175
+ $swapchain.size.times do |i|
176
+ UniformBuffers[i] = device.create_buffer size: UniformBufferStruct.size,
177
+ usage: Vulkan::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
178
+ properties: [:host_visible, :host_coherent]
179
+ end
180
+ descriptor_set_pool = device.create_descriptor_set_pool pool_sizes: [
181
+ {type: :uniform_buffer, count: $swapchain.size},
182
+ {type: :combined_image_sampler, count: $swapchain.size}
183
+ ],
184
+ max_sets: $swapchain.size
185
+ descriptor_set_layout = pipeline.add_descriptor_set_layout descriptors: [{
186
+ binding: 0,
187
+ type: :uniform_buffer,
188
+ stages: [:vertex]
189
+ }, {
190
+ binding: 1,
191
+ type: :combined_image_sampler,
192
+ stages: [:fragment]
193
+ }]
194
+ descriptor_sets = descriptor_set_pool.alloc(layouts: [descriptor_set_layout] * $swapchain.size)
195
+ descriptor_sets.each_with_index do |set, i|
196
+ set[0].set_buffer UniformBuffers[i]
197
+ set[1].set_image_view_and_sampler texture_view, sampler
198
+ set.commit
199
+ end
200
+
201
+ shader_stages.each { |stage| pipeline.add_shader_stage(stage) }
202
+ pipeline.commit(render_pass)
203
+
204
+ $command_buffers = command_pool.create_command_buffers(framebuffers.size) do |cmd, index|
205
+ cmd.render_pass(render_pass, framebuffer: framebuffers[index]) do
206
+ cmd.bind_pipeline(:graphics, pipeline)
207
+ cmd.bind_vertex_buffer(VertexBuffer)
208
+ cmd.bind_index_buffer(IndexBuffer, type: :uint16)
209
+ cmd.bind_descriptor_set(:graphics, descriptor_sets[index], pipeline_layout: pipeline.layout)
210
+ cmd.draw_indexed(IndexData.indices.size, 1, 0, 0, 0)
211
+ end
212
+ end
213
+ end
214
+
215
+ rebuild_swap_chain.call
216
+
217
+ MAX_FRAMES_IN_FLIGHT = 2
218
+ image_available_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
219
+ render_finished_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
220
+ in_flight_fences = MAX_FRAMES_IN_FLIGHT.times.map { device.create_fence signaled: true }
221
+ current_frame = 0
222
+ frame_counter = 0
223
+ start_time = Time.now
224
+ done = false
225
+
226
+ # Begin main event loop & drawing
227
+ until done
228
+ frame_counter += 1
229
+ break if ENV['MAX_FRAMES'].to_i == frame_counter
230
+ # dump some FPS infos
231
+ uptime = ENV['TIME_STEP'] ? ENV['TIME_STEP'].to_f * frame_counter : Time.now - start_time
232
+ if frame_counter % 3000 == 0
233
+ fps = frame_counter / uptime
234
+ p ['fps: ', fps, 'frame-time (ms): ', 1000.0 / fps]
235
+ end
236
+ while event = SDL2::Event.poll
237
+ case event
238
+ when SDL2::Event::Quit, SDL2::Event::KeyDown then done = true
239
+ when SDL2::Event::Window::RESIZED then rebuild_swap_chain.call
240
+ end
241
+ end
242
+
243
+ begin
244
+ in_flight_fences[current_frame].wait_and_reset
245
+ image_index = $swapchain.next_image_index(semaphore: image_available_semaphores[current_frame])
246
+ UniformBuffers[image_index].map do |data|
247
+ Mat4.identity $model_matrix
248
+ $model_matrix.rotate! Vec3.new([0, 0, 1]), uptime * 90.to_radians
249
+ Mat4.look_at Vec3.new([2, 2, 2]), Vec3.zero, Vec3.new([0, 0, 1]), $view_matrix
250
+ Mat4.perspective $projection_matrix, fovy: 45.to_radians,
251
+ aspect: $swapchain.width.to_f / $swapchain.height.to_f,
252
+ near: 0.1,
253
+ far: 10
254
+ $projection_matrix[1][1] *= -1
255
+ data[0, UniformBufferStruct.size] = $ubo[0, UniformBufferStruct.size]
256
+ end
257
+ graphics_queue.submit([$command_buffers[image_index]],
258
+ wait_semaphores: [image_available_semaphores[current_frame]],
259
+ wait_stages: [Vulkan::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
260
+ signal_semaphores: [render_finished_semaphores[current_frame]],
261
+ fence: in_flight_fences[current_frame])
262
+ presentation_queue.present(swapchains: [$swapchain],
263
+ image_indices: [image_index],
264
+ wait_semaphores: [render_finished_semaphores[current_frame]])
265
+ current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT
266
+ rescue Vulkan::Error
267
+ case $!.code
268
+ when Vulkan::VK_ERROR_OUT_OF_DATE_KHR, Vulkan::VK_SUBOPTIMAL_KHR
269
+ rebuild_swap_chain.call
270
+ else raise
271
+ end
272
+ end
273
+ end
274
+
275
+ in_flight_fences.each { |fence| fence.wait_and_reset }
@@ -0,0 +1,315 @@
1
+ # https://vulkan-tutorial.com/code/26_depth_buffering.cpp
2
+
3
+ require 'bundler/setup'
4
+ require 'simplecov'
5
+ require 'vulkan'
6
+ require 'sdl2_vulkan'
7
+ require 'cglm'
8
+ require 'chunky_png'
9
+
10
+ include CGLM
11
+ UniformBufferStruct = Vulkan.struct(['float model[16]', 'float view[16]', 'float proj[16]'])
12
+ def UniformBufferStruct.alignment; Mat4.alignment; end
13
+ $ubo = UniformBufferStruct.new(CGLM.alloc(UniformBufferStruct))
14
+ $model_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('model'))
15
+ $view_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('view'))
16
+ $projection_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('proj'))
17
+
18
+ Vertex = Vulkan.struct(['float pos[3]', 'float color[3]', 'float texcoords[2]'])
19
+ VertexData = Vulkan.struct('vertices[8]' => Vertex).malloc
20
+ VertexData.vertices[0].pos = [-0.5, -0.5, 0.0]; VertexData.vertices[0].color = [1, 0, 0]; VertexData.vertices[0].texcoords = [1, 0]
21
+ VertexData.vertices[1].pos = [ 0.5, -0.5, 0.0]; VertexData.vertices[1].color = [0, 1, 0]; VertexData.vertices[1].texcoords = [0, 0]
22
+ VertexData.vertices[2].pos = [ 0.5, 0.5, 0.0]; VertexData.vertices[2].color = [0, 0, 1]; VertexData.vertices[2].texcoords = [0, 1]
23
+ VertexData.vertices[3].pos = [-0.5, 0.5, 0.0]; VertexData.vertices[3].color = [1, 1, 1]; VertexData.vertices[3].texcoords = [1, 1]
24
+ VertexData.vertices[4].pos = [-0.5, -0.5, -0.5]; VertexData.vertices[4].color = [1, 0, 0]; VertexData.vertices[4].texcoords = [0, 0]
25
+ VertexData.vertices[5].pos = [ 0.5, -0.5, -0.5]; VertexData.vertices[5].color = [0, 1, 0]; VertexData.vertices[5].texcoords = [1, 0]
26
+ VertexData.vertices[6].pos = [ 0.5, 0.5, -0.5]; VertexData.vertices[6].color = [0, 0, 1]; VertexData.vertices[6].texcoords = [1, 1]
27
+ VertexData.vertices[7].pos = [-0.5, 0.5, -0.5]; VertexData.vertices[7].color = [1, 1, 1]; VertexData.vertices[7].texcoords = [0, 1]
28
+ IndexData = Vulkan.struct(['uint16_t indices[12]']).malloc
29
+ IndexData.indices = [0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4]
30
+
31
+ # Create a window that we plan to draw to
32
+ SDL2.init(SDL2::INIT_EVERYTHING)
33
+ window = SDL2::Window.create "test-vulkan", 0, 0, 640, 480, SDL2::Window::Flags::VULKAN |
34
+ SDL2::Window::Flags::RESIZABLE |
35
+ 0x00002000 # SDL2::Window::Flags::ALLOW_HIGHDPI
36
+
37
+ # Create a Vulkan instance
38
+ instance = Vulkan::Instance.new extensions: window.vk_instance_extensions
39
+
40
+ # Create a rendering surface
41
+ surface = instance.create_window_surface(window)
42
+
43
+ # Choose an adequate physical device
44
+ dev = instance.physical_devices.detect do |dev|
45
+ next false unless swapchain_surface_info = dev.swapchain_surface_info(surface)
46
+ builder = Vulkan::SwapchainBuilder.new(swapchain_surface_info)
47
+ dev.properties[:device_type] == :discrete_gpu &&
48
+ (builder.format rescue false) && (builder.presentation_mode rescue false)
49
+ end
50
+ raise 'could not find a suitable physical device' unless dev
51
+
52
+ # Find a queue family that supports graphics
53
+ graphics_queue_family = dev.queue_families.detect do |family|
54
+ family[:queue_count] > 0 && family.supports?(:graphics)
55
+ end
56
+ raise 'no graphics queue family available' unless graphics_queue_family
57
+
58
+ # Find a queue family that supports presentation to the rendering surface
59
+ presentation_queue_family = dev.queue_families.detect do |family|
60
+ family[:queue_count] > 0 && family.supports_presentation?(surface)
61
+ end
62
+ raise 'no graphics queue family available' unless presentation_queue_family
63
+
64
+ # Create a logical device along with the needed extensions and chosen queues
65
+ if graphics_queue_family == presentation_queue_family
66
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] }],
67
+ extensions: ['VK_KHR_swapchain']
68
+ presentation_queue = graphics_queue = device.queue_families[0][:queues][0]
69
+ else
70
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] },
71
+ { family: presentation_queue_family, priorities: [1.0] }],
72
+ extensions: ['VK_KHR_swapchain']
73
+ graphics_queue = device.queue_families[0][:queues][0]
74
+ presentation_queue = device.queue_families[1][:queues][0]
75
+ end
76
+
77
+ command_pool = device.create_command_pool queue_family: graphics_queue_family
78
+
79
+ # Populate the vertex buffer
80
+ staging_buffer = device.create_buffer size: VertexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
81
+ staging_buffer.map { |data| data[0, VertexData.class.size] = VertexData[0, VertexData.class.size] }
82
+ VertexBuffer = device.create_buffer size: VertexData.class.size,
83
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
84
+ properties: :device_local
85
+ vertex_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, VertexBuffer }
86
+
87
+ # Populate the index buffer
88
+ staging_buffer = device.create_buffer size: IndexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
89
+ staging_buffer.map { |data| data[0, IndexData.class.size] = IndexData[0, IndexData.class.size] }
90
+ IndexBuffer = device.create_buffer size: IndexData.class.size,
91
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
92
+ properties: :device_local
93
+ index_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, IndexBuffer }
94
+
95
+ # Submit both transfers and wait for them to complete
96
+ graphics_queue.submit([vertex_transfer_buffer, index_transfer_buffer])
97
+ # graphics_queue.wait_until_idle
98
+
99
+ UniformBuffers = []
100
+
101
+ png = ChunkyPNG::Image.from_file(File.expand_path('textures/texture.png', __dir__))
102
+ image_data = png.to_rgba_stream
103
+ image_data_buffer = device.create_buffer size: image_data.size,
104
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
105
+ properties: [:host_visible, :host_coherent]
106
+ image_data_buffer.map { |data| data[0, image_data.size] = image_data }
107
+ texture = device.create_image dimensions: 2,
108
+ width: png.width,
109
+ height: png.height,
110
+ depth: 1,
111
+ mip_levels: 1,
112
+ array_layers: 1,
113
+ format: :r8g8b8a8_unorm,
114
+ tiling: :optimal,
115
+ initial_layout: :undefined,
116
+ usage: [:transfer_dst, :sampled],
117
+ sharing: :exclusive,
118
+ samples: 1
119
+ texture.transition_layout command_pool, graphics_queue, to: :transfer_dst_optimal
120
+ texture.copy_from_buffer command_pool, graphics_queue, buffer: image_data_buffer, width: png.width, height: png.height
121
+ graphics_queue.wait_until_idle
122
+ texture.transition_layout command_pool, graphics_queue, to: :shader_ro_optimal
123
+ texture_view = texture.create_view
124
+ sampler = device.create_sampler
125
+
126
+ shader_stages = [
127
+ device.create_shader_stage(file_path: File.expand_path('./shaders/depth_buffering.vert.spv', __dir__),
128
+ stage: Vulkan::VK_SHADER_STAGE_VERTEX_BIT),
129
+ device.create_shader_stage(file_path: File.expand_path('./shaders/textures.frag.spv', __dir__),
130
+ stage: Vulkan::VK_SHADER_STAGE_FRAGMENT_BIT)
131
+ ]
132
+
133
+ rebuild_swap_chain = proc do
134
+ # Create a swapchain for image presentation
135
+ $swapchain = device.create_swapchain surface: surface,
136
+ surface_width: window.vk_drawable_size[0],
137
+ surface_height: window.vk_drawable_size[1]
138
+
139
+ # Create render pass with one subpass
140
+ render_pass = device.create_renderpass
141
+ depth_format = device.physical_device.detect_supported_format(
142
+ :d32_sfloat, :d32_sfloat_s8_uint, :d24_unorm_s8_uint,
143
+ usage: :depth_stencil_attachment,
144
+ tiling: :optimal
145
+ )
146
+ depth_attachment_index = render_pass.add_attachment format: depth_format,
147
+ samples: 1,
148
+ load_op: :clear,
149
+ store_op: :dont_care,
150
+ stencil_load_op: :dont_care,
151
+ stencil_store_op: :dont_care,
152
+ initial_layout: nil,
153
+ final_layout: :depth_stencil_attachment
154
+ subpass = render_pass.add_subpass
155
+ subpass.add_color_attachment_ref index: render_pass.add_attachment(format: $swapchain.format)
156
+ subpass.set_depth_stencil_attachment_ref index: depth_attachment_index
157
+ render_pass.commit
158
+
159
+ depth_image = device.create_image dimensions: 2,
160
+ width: $swapchain.width,
161
+ height: $swapchain.height,
162
+ depth: 1,
163
+ mip_levels: 1,
164
+ array_layers: 1,
165
+ format: depth_format,
166
+ tiling: :optimal,
167
+ initial_layout: :undefined,
168
+ usage: [:depth_stencil_attachment],
169
+ sharing: :exclusive,
170
+ samples: 1
171
+ depth_image_view = depth_image.create_view aspects: :depth
172
+ depth_image.transition_layout command_pool, graphics_queue, to: :depth_stencil_attachment_optimal,
173
+ aspects: :depth
174
+
175
+ # Create a framebuffer for each image in the swap chain, and associate each with the depth image
176
+ framebuffers = $swapchain.image_views.map do |swapchain_image_view|
177
+ device.create_framebuffer(width: $swapchain.width,
178
+ height: $swapchain.height,
179
+ render_pass: render_pass,
180
+ attachments: [depth_image_view,
181
+ swapchain_image_view])
182
+ end
183
+
184
+ # Create graphic pipeline
185
+ pipeline = device.create_pipeline(viewport: { width: $swapchain.width, height: $swapchain.height })
186
+ pipeline.depth
187
+ pipeline.add_binding_description binding: 0,
188
+ stride: Vertex.size,
189
+ input_rate: Vulkan::VK_VERTEX_INPUT_RATE_VERTEX
190
+
191
+ pipeline.add_attribute_description binding: 0,
192
+ location: 0,
193
+ format: :r32g32b32_sfloat,
194
+ offset: 0
195
+
196
+ pipeline.add_attribute_description binding: 0,
197
+ location: 1,
198
+ format: :r32g32b32_sfloat,
199
+ offset: Fiddle::SIZEOF_FLOAT * 3
200
+
201
+ pipeline.add_attribute_description binding: 0,
202
+ location: 2,
203
+ format: :r32g32_sfloat,
204
+ offset: Fiddle::SIZEOF_FLOAT * 6
205
+
206
+ # Create a uniform buffer for each image in the swapchain, so that we don't
207
+ # modify a buffer for a frame still in-flight
208
+ UniformBuffers.clear
209
+ $swapchain.size.times do |i|
210
+ UniformBuffers[i] = device.create_buffer size: UniformBufferStruct.size,
211
+ usage: Vulkan::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
212
+ properties: [:host_visible, :host_coherent]
213
+ end
214
+ descriptor_set_pool = device.create_descriptor_set_pool pool_sizes: [
215
+ {type: :uniform_buffer, count: $swapchain.size},
216
+ {type: :combined_image_sampler, count: $swapchain.size}
217
+ ],
218
+ max_sets: $swapchain.size
219
+ descriptor_set_layout = pipeline.add_descriptor_set_layout descriptors: [{
220
+ binding: 0,
221
+ type: :uniform_buffer,
222
+ stages: [:vertex]
223
+ }, {
224
+ binding: 1,
225
+ type: :combined_image_sampler,
226
+ stages: [:fragment]
227
+ }]
228
+ descriptor_sets = descriptor_set_pool.alloc(layouts: [descriptor_set_layout] * $swapchain.size)
229
+ descriptor_sets.each_with_index do |set, i|
230
+ set[0].set_buffer UniformBuffers[i]
231
+ set[1].set_image_view_and_sampler texture_view, sampler
232
+ set.commit
233
+ end
234
+
235
+ shader_stages.each { |stage| pipeline.add_shader_stage(stage) }
236
+ pipeline.commit(render_pass)
237
+
238
+ $command_buffers = command_pool.create_command_buffers(framebuffers.size) do |cmd, index|
239
+ cmd.render_pass(render_pass, framebuffer: framebuffers[index]) do
240
+ cmd.bind_pipeline(:graphics, pipeline)
241
+ cmd.bind_vertex_buffer(VertexBuffer)
242
+ cmd.bind_index_buffer(IndexBuffer, type: :uint16)
243
+ cmd.bind_descriptor_set(:graphics, descriptor_sets[index], pipeline_layout: pipeline.layout)
244
+ cmd.draw_indexed(IndexData.indices.size, 1, 0, 0, 0)
245
+ end
246
+ end
247
+ end
248
+
249
+ rebuild_swap_chain.call
250
+
251
+ MAX_FRAMES_IN_FLIGHT = 2
252
+ image_available_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
253
+ render_finished_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
254
+ in_flight_fences = MAX_FRAMES_IN_FLIGHT.times.map { device.create_fence signaled: true }
255
+ current_frame = 0
256
+ frame_counter = 0
257
+ start_time = Time.now
258
+ done = false
259
+
260
+ # Begin main event loop & drawing
261
+ until done
262
+ frame_counter += 1
263
+ break if ENV['MAX_FRAMES'].to_i == frame_counter
264
+ # dump some FPS infos
265
+ uptime = ENV['TIME_STEP'] ? ENV['TIME_STEP'].to_f * frame_counter : Time.now - start_time
266
+ if frame_counter % 3000 == 0
267
+ fps = frame_counter / uptime
268
+ p ['fps: ', fps, 'frame-time (ms): ', 1000.0 / fps]
269
+ end
270
+ while event = SDL2::Event.poll
271
+ case event
272
+ when SDL2::Event::Quit, SDL2::Event::KeyDown then done = true
273
+ when SDL2::Event::Window::RESIZED then rebuild_swap_chain.call
274
+ end
275
+ end
276
+
277
+ begin
278
+ in_flight_fences[current_frame].wait_and_reset
279
+ image_index = $swapchain.next_image_index(semaphore: image_available_semaphores[current_frame])
280
+ UniformBuffers[image_index].map do |data|
281
+ Mat4.identity $model_matrix
282
+ $model_matrix.rotate! Vec3.new([0, 0, 1]), uptime * 90.to_radians
283
+ Mat4.look_at Vec3.new([2, 2, 2]), Vec3.zero, Vec3.new([0, 0, 1]), $view_matrix
284
+ Mat4.perspective $projection_matrix, fovy: 45.to_radians,
285
+ aspect: $swapchain.width.to_f / $swapchain.height.to_f,
286
+ near: 0.1,
287
+ far: 10
288
+ # Convert OpenGL projection matrix into Vulkan projection matrix
289
+ # (e.g. NDC from z=-1..1 to z=0..1, and flip y)
290
+ $projection_matrix.mul_mat4 Mat4.new([Vec4.new([1.0, 0.0, 0.0, 0.0]),
291
+ Vec4.new([0.0, -1.0, 0.0, 0.0]),
292
+ Vec4.new([0.0, 0.0, 0.5, -0.5]),
293
+ Vec4.new([0.0, 0.0, 0.0, 1.0])]),
294
+ $projection_matrix
295
+ data[0, UniformBufferStruct.size] = $ubo[0, UniformBufferStruct.size]
296
+ end
297
+ graphics_queue.submit([$command_buffers[image_index]],
298
+ wait_semaphores: [image_available_semaphores[current_frame]],
299
+ wait_stages: [Vulkan::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
300
+ signal_semaphores: [render_finished_semaphores[current_frame]],
301
+ fence: in_flight_fences[current_frame])
302
+ presentation_queue.present(swapchains: [$swapchain],
303
+ image_indices: [image_index],
304
+ wait_semaphores: [render_finished_semaphores[current_frame]])
305
+ current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT
306
+ rescue Vulkan::Error
307
+ case $!.code
308
+ when Vulkan::VK_ERROR_OUT_OF_DATE_KHR, Vulkan::VK_SUBOPTIMAL_KHR
309
+ rebuild_swap_chain.call
310
+ else raise
311
+ end
312
+ end
313
+ end
314
+
315
+ in_flight_fences.each { |fence| fence.wait_and_reset }