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,174 @@
1
+ # https://vulkan-tutorial.com/code/19_staging_buffer.cpp
2
+
3
+ require 'bundler/setup'
4
+ require 'simplecov'
5
+ require 'vulkan'
6
+ require 'sdl2_vulkan'
7
+
8
+ Vertex = Vulkan.struct(['float pos[2]', 'float color[3]'])
9
+ VertexData = Vulkan.struct('vertices[3]' => Vertex).malloc
10
+ VertexData.vertices[0].pos = [ 0, -0.5]; VertexData.vertices[0].color = [1, 0, 0]
11
+ VertexData.vertices[1].pos = [-0.5, 0.5]; VertexData.vertices[1].color = [0, 1, 0]
12
+ VertexData.vertices[2].pos = [ 0.5, 0.5]; VertexData.vertices[2].color = [0, 0, 1]
13
+
14
+ # Create a window that we plan to draw to
15
+ SDL2.init(SDL2::INIT_EVERYTHING)
16
+ window = SDL2::Window.create "test-vulkan", 0, 0, 640, 480, SDL2::Window::Flags::VULKAN |
17
+ SDL2::Window::Flags::RESIZABLE |
18
+ 0x00002000 # SDL2::Window::Flags::ALLOW_HIGHDPI
19
+
20
+ # Create a Vulkan instance
21
+ instance = Vulkan::Instance.new extensions: window.vk_instance_extensions
22
+
23
+ # Create a rendering surface
24
+ surface = instance.create_window_surface(window)
25
+
26
+ # Choose an adequate physical device
27
+ dev = instance.physical_devices.detect do |dev|
28
+ next false unless swapchain_surface_info = dev.swapchain_surface_info(surface)
29
+ builder = Vulkan::SwapchainBuilder.new(swapchain_surface_info)
30
+ dev.properties[:device_type] == :discrete_gpu &&
31
+ (builder.format rescue false) && (builder.presentation_mode rescue false)
32
+ end
33
+ raise 'could not find a suitable physical device' unless dev
34
+
35
+ # Find a queue family that supports graphics
36
+ graphics_queue_family = dev.queue_families.detect do |family|
37
+ family[:queue_count] > 0 && family.supports?(:graphics)
38
+ end
39
+ raise 'no graphics queue family available' unless graphics_queue_family
40
+
41
+ # Find a queue family that supports presentation to the rendering surface
42
+ presentation_queue_family = dev.queue_families.detect do |family|
43
+ family[:queue_count] > 0 && family.supports_presentation?(surface)
44
+ end
45
+ raise 'no graphics queue family available' unless presentation_queue_family
46
+
47
+ # Create a logical device along with the needed extensions and chosen queues
48
+ if graphics_queue_family == presentation_queue_family
49
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] }],
50
+ extensions: ['VK_KHR_swapchain']
51
+ presentation_queue = graphics_queue = device.queue_families[0][:queues][0]
52
+ else
53
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] },
54
+ { family: presentation_queue_family, priorities: [1.0] }],
55
+ extensions: ['VK_KHR_swapchain']
56
+ graphics_queue = device.queue_families[0][:queues][0]
57
+ presentation_queue = device.queue_families[1][:queues][0]
58
+ end
59
+
60
+ command_pool = device.create_command_pool queue_family: graphics_queue_family
61
+
62
+ StagingBuffer = device.create_buffer size: VertexData.class.size,
63
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
64
+ StagingBuffer.map do |data|
65
+ data[0, VertexData.class.size] = VertexData[0, VertexData.class.size]
66
+ end
67
+
68
+ VertexBuffer = device.create_buffer size: VertexData.class.size,
69
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
70
+ properties: :device_local
71
+ transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) do |cmd|
72
+ cmd.copy_buffer StagingBuffer, VertexBuffer
73
+ end
74
+ graphics_queue.submit([transfer_buffer])
75
+ graphics_queue.wait_until_idle
76
+
77
+ shader_stages = [
78
+ device.create_shader_stage(file_path: File.expand_path('./shaders/vertex_buffer.vert.spv', __dir__),
79
+ stage: Vulkan::VK_SHADER_STAGE_VERTEX_BIT),
80
+ device.create_shader_stage(file_path: File.expand_path('./shaders/triangle.frag.spv', __dir__),
81
+ stage: Vulkan::VK_SHADER_STAGE_FRAGMENT_BIT)
82
+ ]
83
+
84
+ rebuild_swap_chain = proc do
85
+ # Create a swapchain for image presentation
86
+ $swapchain = device.create_swapchain surface: surface,
87
+ surface_width: window.vk_drawable_size[0],
88
+ surface_height: window.vk_drawable_size[1]
89
+
90
+ # Create render pass with one subpass
91
+ render_pass = device.create_renderpass
92
+ subpass = render_pass.add_subpass
93
+ subpass.add_color_attachment_ref index: render_pass.add_attachment(format: $swapchain.format),
94
+ layout: :color
95
+ render_pass.commit
96
+
97
+ # Create a framebuffer for each image in the swap chain
98
+ framebuffers = $swapchain.image_views.map do |swapchain_image_view|
99
+ device.create_framebuffer(width: $swapchain.width,
100
+ height: $swapchain.height,
101
+ render_pass: render_pass,
102
+ attachments: [swapchain_image_view])
103
+ end
104
+
105
+ # Create graphic pipeline
106
+ pipeline = device.create_pipeline(viewport: { width: $swapchain.width, height: $swapchain.height })
107
+ pipeline.add_binding_description binding: 0,
108
+ stride: Vertex.size,
109
+ input_rate: Vulkan::VK_VERTEX_INPUT_RATE_VERTEX
110
+
111
+ pipeline.add_attribute_description binding: 0,
112
+ location: 0,
113
+ format: Vulkan::VK_FORMAT_R32G32_SFLOAT,
114
+ offset: Vertex.offsetof('pos')
115
+
116
+ pipeline.add_attribute_description binding: 0,
117
+ location: 1,
118
+ format: Vulkan::VK_FORMAT_R32G32B32_SFLOAT,
119
+ offset: Vertex.offsetof('color')
120
+ shader_stages.each { |stage| pipeline.add_shader_stage(stage) }
121
+ pipeline.commit(render_pass)
122
+
123
+ $command_buffers = command_pool.create_command_buffers(framebuffers.size) do |cmd, index|
124
+ cmd.render_pass(render_pass, framebuffer: framebuffers[index]) do
125
+ cmd.bind_pipeline(:graphics, pipeline)
126
+ cmd.bind_vertex_buffer(VertexBuffer)
127
+ cmd.draw(VertexData.vertices.size, 1, 0, 0)
128
+ end
129
+ end
130
+ end
131
+
132
+ rebuild_swap_chain.call
133
+
134
+ MAX_FRAMES_IN_FLIGHT = 2
135
+ image_available_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
136
+ render_finished_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
137
+ in_flight_fences = MAX_FRAMES_IN_FLIGHT.times.map { device.create_fence signaled: true }
138
+ current_frame = 0
139
+ frame_counter = 0
140
+ done = false
141
+
142
+ # Begin main event loop & drawing
143
+ until done
144
+ frame_counter += 1
145
+ break if ENV['MAX_FRAMES'].to_i == frame_counter
146
+ while event = SDL2::Event.poll
147
+ case event
148
+ when SDL2::Event::Quit, SDL2::Event::KeyDown then done = true
149
+ when SDL2::Event::Window::RESIZED then rebuild_swap_chain.call
150
+ end
151
+ end
152
+
153
+ begin
154
+ in_flight_fences[current_frame].wait_and_reset
155
+ image_index = $swapchain.next_image_index(semaphore: image_available_semaphores[current_frame])
156
+ graphics_queue.submit([$command_buffers[image_index]],
157
+ wait_semaphores: [image_available_semaphores[current_frame]],
158
+ wait_stages: [Vulkan::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
159
+ signal_semaphores: [render_finished_semaphores[current_frame]],
160
+ fence: in_flight_fences[current_frame])
161
+ presentation_queue.present(swapchains: [$swapchain],
162
+ image_indices: [image_index],
163
+ wait_semaphores: [render_finished_semaphores[current_frame]])
164
+ current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT
165
+ rescue Vulkan::Error
166
+ case $!.code
167
+ when Vulkan::VK_ERROR_OUT_OF_DATE_KHR, Vulkan::VK_SUBOPTIMAL_KHR
168
+ rebuild_swap_chain.call
169
+ else raise
170
+ end
171
+ end
172
+ end
173
+
174
+ in_flight_fences.each { |fence| fence.wait_and_reset }
@@ -0,0 +1,193 @@
1
+ # https://vulkan-tutorial.com/code/20_index_buffer.cpp
2
+
3
+ require 'bundler/setup'
4
+ require 'simplecov'
5
+ require 'vulkan'
6
+ require 'sdl2_vulkan'
7
+
8
+ Vertex = Vulkan.struct(['float pos[2]', 'float color[3]'])
9
+ VertexData = Vulkan.struct('vertices[4]' => Vertex).malloc
10
+ VertexData.vertices[0].pos = [-0.5, -0.5]; VertexData.vertices[0].color = [1, 0, 0]
11
+ VertexData.vertices[1].pos = [ 0.5, -0.5]; VertexData.vertices[1].color = [0, 1, 0]
12
+ VertexData.vertices[2].pos = [ 0.5, 0.5]; VertexData.vertices[2].color = [0, 0, 1]
13
+ VertexData.vertices[3].pos = [-0.5, 0.5]; VertexData.vertices[3].color = [1, 1, 1]
14
+
15
+ IndexData = Vulkan.struct(['uint16_t indices[6]']).malloc
16
+ IndexData.indices = [1, 0, 2, 2, 0, 3]
17
+
18
+ # Create a window that we plan to draw to
19
+ SDL2.init(SDL2::INIT_EVERYTHING)
20
+ window = SDL2::Window.create "test-vulkan", 0, 0, 640, 480, SDL2::Window::Flags::VULKAN |
21
+ SDL2::Window::Flags::RESIZABLE |
22
+ 0x00002000 # SDL2::Window::Flags::ALLOW_HIGHDPI
23
+
24
+ # Create a Vulkan instance
25
+ instance = Vulkan::Instance.new extensions: window.vk_instance_extensions
26
+
27
+ # Create a rendering surface
28
+ surface = instance.create_window_surface(window)
29
+
30
+ # Choose an adequate physical device
31
+ dev = instance.physical_devices.detect do |dev|
32
+ next false unless swapchain_surface_info = dev.swapchain_surface_info(surface)
33
+ builder = Vulkan::SwapchainBuilder.new(swapchain_surface_info)
34
+ dev.properties[:device_type] == :discrete_gpu &&
35
+ (builder.format rescue false) && (builder.presentation_mode rescue false)
36
+ end
37
+ raise 'could not find a suitable physical device' unless dev
38
+
39
+ # Find a queue family that supports graphics
40
+ graphics_queue_family = dev.queue_families.detect do |family|
41
+ family[:queue_count] > 0 && family.supports?(:graphics)
42
+ end
43
+ raise 'no graphics queue family available' unless graphics_queue_family
44
+
45
+ # Find a queue family that supports presentation to the rendering surface
46
+ presentation_queue_family = dev.queue_families.detect do |family|
47
+ family[:queue_count] > 0 && family.supports_presentation?(surface)
48
+ end
49
+ raise 'no graphics queue family available' unless presentation_queue_family
50
+
51
+ # Create a logical device along with the needed extensions and chosen queues
52
+ if graphics_queue_family == presentation_queue_family
53
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] }],
54
+ extensions: ['VK_KHR_swapchain']
55
+ presentation_queue = graphics_queue = device.queue_families[0][:queues][0]
56
+ else
57
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] },
58
+ { family: presentation_queue_family, priorities: [1.0] }],
59
+ extensions: ['VK_KHR_swapchain']
60
+ graphics_queue = device.queue_families[0][:queues][0]
61
+ presentation_queue = device.queue_families[1][:queues][0]
62
+ end
63
+
64
+ command_pool = device.create_command_pool queue_family: graphics_queue_family
65
+
66
+ # Populate the vertex buffer
67
+ staging_buffer = device.create_buffer size: VertexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
68
+ staging_buffer.map { |data| data[0, VertexData.class.size] = VertexData[0, VertexData.class.size] }
69
+ VertexBuffer = device.create_buffer size: VertexData.class.size,
70
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
71
+ properties: :device_local
72
+ vertex_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, VertexBuffer }
73
+
74
+ # Populate the index buffer
75
+ staging_buffer = device.create_buffer size: IndexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
76
+ staging_buffer.map { |data| data[0, IndexData.class.size] = IndexData[0, IndexData.class.size] }
77
+ IndexBuffer = device.create_buffer size: IndexData.class.size,
78
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
79
+ properties: :device_local
80
+ index_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, IndexBuffer }
81
+
82
+ # Submit both transfers and wait for them to complete
83
+ graphics_queue.submit([vertex_transfer_buffer, index_transfer_buffer])
84
+ graphics_queue.wait_until_idle
85
+
86
+
87
+ shader_stages = [
88
+ device.create_shader_stage(file_path: File.expand_path('./shaders/vertex_buffer.vert.spv', __dir__),
89
+ stage: Vulkan::VK_SHADER_STAGE_VERTEX_BIT),
90
+ device.create_shader_stage(file_path: File.expand_path('./shaders/triangle.frag.spv', __dir__),
91
+ stage: Vulkan::VK_SHADER_STAGE_FRAGMENT_BIT)
92
+ ]
93
+
94
+ rebuild_swap_chain = proc do
95
+ # Create a swapchain for image presentation
96
+ $swapchain = device.create_swapchain surface: surface,
97
+ surface_width: window.vk_drawable_size[0],
98
+ surface_height: window.vk_drawable_size[1]
99
+
100
+ # Create render pass with one subpass
101
+ render_pass = device.create_renderpass
102
+ subpass = render_pass.add_subpass
103
+ subpass.add_color_attachment_ref index: render_pass.add_attachment(format: $swapchain.format),
104
+ layout: :color
105
+ render_pass.commit
106
+
107
+ # Create a framebuffer for each image in the swap chain
108
+ framebuffers = $swapchain.image_views.map do |swapchain_image_view|
109
+ device.create_framebuffer(width: $swapchain.width,
110
+ height: $swapchain.height,
111
+ render_pass: render_pass,
112
+ attachments: [swapchain_image_view])
113
+ end
114
+
115
+ # Create graphic pipeline
116
+ pipeline = device.create_pipeline(viewport: { width: $swapchain.width, height: $swapchain.height })
117
+ pipeline.add_binding_description binding: 0,
118
+ stride: Vertex.size,
119
+ input_rate: Vulkan::VK_VERTEX_INPUT_RATE_VERTEX
120
+
121
+ pipeline.add_attribute_description binding: 0,
122
+ location: 0,
123
+ format: Vulkan::VK_FORMAT_R32G32_SFLOAT,
124
+ offset: Vertex.offsetof('pos')
125
+
126
+ pipeline.add_attribute_description binding: 0,
127
+ location: 1,
128
+ format: Vulkan::VK_FORMAT_R32G32B32_SFLOAT,
129
+ offset: Vertex.offsetof('color')
130
+ shader_stages.each { |stage| pipeline.add_shader_stage(stage) }
131
+ pipeline.commit(render_pass)
132
+
133
+ $command_buffers = command_pool.create_command_buffers(framebuffers.size) do |cmd, index|
134
+ cmd.render_pass(render_pass, framebuffer: framebuffers[index]) do
135
+ cmd.bind_pipeline(:graphics, pipeline)
136
+ cmd.bind_vertex_buffer(VertexBuffer)
137
+ cmd.bind_index_buffer(IndexBuffer, type: :uint16)
138
+ cmd.draw_indexed(IndexData.indices.size, 1, 0, 0, 0)
139
+ end
140
+ end
141
+ end
142
+
143
+ rebuild_swap_chain.call
144
+
145
+ MAX_FRAMES_IN_FLIGHT = 2
146
+ image_available_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
147
+ render_finished_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
148
+ in_flight_fences = MAX_FRAMES_IN_FLIGHT.times.map { device.create_fence signaled: true }
149
+ current_frame = 0
150
+ frame_counter = 0
151
+ last_time = Time.now
152
+ done = false
153
+
154
+ # Begin main event loop & drawing
155
+ until done
156
+ frame_counter += 1
157
+ break if ENV['MAX_FRAMES'].to_i == frame_counter
158
+ # dump some FPS infos
159
+ if frame_counter % 3000 == 0
160
+ next_time = Time.now
161
+ seconds = next_time - last_time
162
+ fps = frame_counter / seconds
163
+ p ['fps: ', fps, 'frame-time (ms): ', 1000.0 / fps]
164
+ end
165
+ while event = SDL2::Event.poll
166
+ case event
167
+ when SDL2::Event::Quit, SDL2::Event::KeyDown then done = true
168
+ when SDL2::Event::Window::RESIZED then rebuild_swap_chain.call
169
+ end
170
+ end
171
+
172
+ begin
173
+ in_flight_fences[current_frame].wait_and_reset
174
+ image_index = $swapchain.next_image_index(semaphore: image_available_semaphores[current_frame])
175
+ graphics_queue.submit([$command_buffers[image_index]],
176
+ wait_semaphores: [image_available_semaphores[current_frame]],
177
+ wait_stages: [Vulkan::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
178
+ signal_semaphores: [render_finished_semaphores[current_frame]],
179
+ fence: in_flight_fences[current_frame])
180
+ presentation_queue.present(swapchains: [$swapchain],
181
+ image_indices: [image_index],
182
+ wait_semaphores: [render_finished_semaphores[current_frame]])
183
+ current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT
184
+ rescue Vulkan::Error
185
+ case $!.code
186
+ when Vulkan::VK_ERROR_OUT_OF_DATE_KHR, Vulkan::VK_SUBOPTIMAL_KHR
187
+ rebuild_swap_chain.call
188
+ else raise
189
+ end
190
+ end
191
+ end
192
+
193
+ in_flight_fences.each { |fence| fence.wait_and_reset }
@@ -0,0 +1,237 @@
1
+ # https://vulkan-tutorial.com/code/22_descriptor_sets.cpp
2
+
3
+ require 'bundler/setup'
4
+ require 'simplecov'
5
+ require 'vulkan'
6
+ require 'sdl2_vulkan'
7
+ require 'cglm'
8
+
9
+ include CGLM
10
+ UniformBufferStruct = Vulkan.struct(['float model[16]', 'float view[16]', 'float proj[16]'])
11
+ def UniformBufferStruct.alignment; Mat4.alignment; end
12
+ $ubo = UniformBufferStruct.new(CGLM.alloc(UniformBufferStruct))
13
+ $model_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('model'))
14
+ $view_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('view'))
15
+ $projection_matrix = Mat4.new(addr: $ubo.to_ptr + UniformBufferStruct.offsetof('proj'))
16
+
17
+ Vertex = Vulkan.struct(['float pos[2]', 'float color[3]'])
18
+ VertexData = Vulkan.struct('vertices[4]' => Vertex).malloc
19
+ VertexData.vertices[0].pos = [-0.5, -0.5]; VertexData.vertices[0].color = [1, 0, 0]
20
+ VertexData.vertices[1].pos = [ 0.5, -0.5]; VertexData.vertices[1].color = [0, 1, 0]
21
+ VertexData.vertices[2].pos = [ 0.5, 0.5]; VertexData.vertices[2].color = [0, 0, 1]
22
+ VertexData.vertices[3].pos = [-0.5, 0.5]; VertexData.vertices[3].color = [1, 1, 1]
23
+
24
+ IndexData = Vulkan.struct(['uint16_t indices[6]']).malloc
25
+ IndexData.indices = [0, 1, 2, 2, 3, 0]
26
+
27
+ # Create a window that we plan to draw to
28
+ SDL2.init(SDL2::INIT_EVERYTHING)
29
+ window = SDL2::Window.create "test-vulkan", 0, 0, 640, 480, SDL2::Window::Flags::VULKAN |
30
+ SDL2::Window::Flags::RESIZABLE |
31
+ 0x00002000 # SDL2::Window::Flags::ALLOW_HIGHDPI
32
+
33
+ # Create a Vulkan instance
34
+ instance = Vulkan::Instance.new extensions: window.vk_instance_extensions
35
+
36
+ # Create a rendering surface
37
+ surface = instance.create_window_surface(window)
38
+
39
+ # Choose an adequate physical device
40
+ dev = instance.physical_devices.detect do |dev|
41
+ next false unless swapchain_surface_info = dev.swapchain_surface_info(surface)
42
+ builder = Vulkan::SwapchainBuilder.new(swapchain_surface_info)
43
+ dev.properties[:device_type] == :discrete_gpu &&
44
+ (builder.format rescue false) && (builder.presentation_mode rescue false)
45
+ end
46
+ raise 'could not find a suitable physical device' unless dev
47
+
48
+ # Find a queue family that supports graphics
49
+ graphics_queue_family = dev.queue_families.detect do |family|
50
+ family[:queue_count] > 0 && family.supports?(:graphics)
51
+ end
52
+ raise 'no graphics queue family available' unless graphics_queue_family
53
+
54
+ # Find a queue family that supports presentation to the rendering surface
55
+ presentation_queue_family = dev.queue_families.detect do |family|
56
+ family[:queue_count] > 0 && family.supports_presentation?(surface)
57
+ end
58
+ raise 'no graphics queue family available' unless presentation_queue_family
59
+
60
+ # Create a logical device along with the needed extensions and chosen queues
61
+ if graphics_queue_family == presentation_queue_family
62
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] }],
63
+ extensions: ['VK_KHR_swapchain']
64
+ presentation_queue = graphics_queue = device.queue_families[0][:queues][0]
65
+ else
66
+ device = dev.create queues: [{ family: graphics_queue_family, priorities: [1.0] },
67
+ { family: presentation_queue_family, priorities: [1.0] }],
68
+ extensions: ['VK_KHR_swapchain']
69
+ graphics_queue = device.queue_families[0][:queues][0]
70
+ presentation_queue = device.queue_families[1][:queues][0]
71
+ end
72
+
73
+ command_pool = device.create_command_pool queue_family: graphics_queue_family
74
+
75
+ # Populate the vertex buffer
76
+ staging_buffer = device.create_buffer size: VertexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
77
+ staging_buffer.map { |data| data[0, VertexData.class.size] = VertexData[0, VertexData.class.size] }
78
+ VertexBuffer = device.create_buffer size: VertexData.class.size,
79
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
80
+ properties: :device_local
81
+ vertex_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, VertexBuffer }
82
+
83
+ # Populate the index buffer
84
+ staging_buffer = device.create_buffer size: IndexData.class.size, usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
85
+ staging_buffer.map { |data| data[0, IndexData.class.size] = IndexData[0, IndexData.class.size] }
86
+ IndexBuffer = device.create_buffer size: IndexData.class.size,
87
+ usage: Vulkan::VK_BUFFER_USAGE_TRANSFER_DST_BIT | Vulkan::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
88
+ properties: :device_local
89
+ index_transfer_buffer = command_pool.create_command_buffer(usage: :one_time_submit) { |cmd| cmd.copy_buffer staging_buffer, IndexBuffer }
90
+
91
+ UniformBuffers = []
92
+
93
+ # Submit both transfers and wait for them to complete
94
+ graphics_queue.submit([vertex_transfer_buffer, index_transfer_buffer])
95
+ graphics_queue.wait_until_idle
96
+
97
+
98
+ shader_stages = [
99
+ device.create_shader_stage(file_path: File.expand_path('./shaders/uniform_buffer.vert.spv', __dir__),
100
+ stage: Vulkan::VK_SHADER_STAGE_VERTEX_BIT),
101
+ device.create_shader_stage(file_path: File.expand_path('./shaders/triangle.frag.spv', __dir__),
102
+ stage: Vulkan::VK_SHADER_STAGE_FRAGMENT_BIT)
103
+ ]
104
+
105
+ rebuild_swap_chain = proc do
106
+ # Create a swapchain for image presentation
107
+ $swapchain = device.create_swapchain surface: surface,
108
+ surface_width: window.vk_drawable_size[0],
109
+ surface_height: window.vk_drawable_size[1]
110
+
111
+ # Create render pass with one subpass
112
+ render_pass = device.create_renderpass
113
+ subpass = render_pass.add_subpass
114
+ subpass.add_color_attachment_ref index: render_pass.add_attachment(format: $swapchain.format),
115
+ layout: :color
116
+ render_pass.commit
117
+
118
+ # Create a framebuffer for each image in the swap chain
119
+ framebuffers = $swapchain.image_views.map do |swapchain_image_view|
120
+ device.create_framebuffer(width: $swapchain.width,
121
+ height: $swapchain.height,
122
+ render_pass: render_pass,
123
+ attachments: [swapchain_image_view])
124
+ end
125
+
126
+ # Create graphic pipeline
127
+ pipeline = device.create_pipeline(viewport: { width: $swapchain.width, height: $swapchain.height })
128
+ pipeline.add_binding_description binding: 0,
129
+ stride: Vertex.size,
130
+ input_rate: Vulkan::VK_VERTEX_INPUT_RATE_VERTEX
131
+
132
+ pipeline.add_attribute_description binding: 0,
133
+ location: 0,
134
+ format: Vulkan::VK_FORMAT_R32G32_SFLOAT,
135
+ offset: Vertex.offsetof('pos')
136
+
137
+ pipeline.add_attribute_description binding: 0,
138
+ location: 1,
139
+ format: Vulkan::VK_FORMAT_R32G32B32_SFLOAT,
140
+ offset: Vertex.offsetof('color')
141
+
142
+ # Create a uniform buffer for each image in the swapchain, so that we don't
143
+ # modify a buffer for a frame still in-flight
144
+ UniformBuffers.clear
145
+ $swapchain.size.times do |i|
146
+ UniformBuffers[i] = device.create_buffer size: UniformBufferStruct.size,
147
+ usage: Vulkan::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
148
+ properties: [:host_visible, :host_coherent]
149
+ end
150
+ descriptor_set_pool = device.create_descriptor_set_pool pool_sizes: [type: :uniform_buffer, count: $swapchain.size],
151
+ max_sets: $swapchain.size
152
+ descriptor_set_layout = pipeline.add_descriptor_set_layout descriptors: [{
153
+ binding: 0,
154
+ type: :uniform_buffer,
155
+ stages: [:vertex]
156
+ }]
157
+ descriptor_sets = descriptor_set_pool.alloc(layouts: [descriptor_set_layout] * $swapchain.size)
158
+ descriptor_sets.each_with_index do |set, i|
159
+ set[0].set_buffer UniformBuffers[i]
160
+ set.commit
161
+ end
162
+
163
+ shader_stages.each { |stage| pipeline.add_shader_stage(stage) }
164
+ pipeline.commit(render_pass)
165
+
166
+ $command_buffers = command_pool.create_command_buffers(framebuffers.size) do |cmd, index|
167
+ cmd.render_pass(render_pass, framebuffer: framebuffers[index]) do
168
+ cmd.bind_pipeline(:graphics, pipeline)
169
+ cmd.bind_vertex_buffer(VertexBuffer)
170
+ cmd.bind_index_buffer(IndexBuffer, type: :uint16)
171
+ cmd.bind_descriptor_set(:graphics, descriptor_sets[index], pipeline_layout: pipeline.layout)
172
+ cmd.draw_indexed(IndexData.indices.size, 1, 0, 0, 0)
173
+ end
174
+ end
175
+ end
176
+
177
+ rebuild_swap_chain.call
178
+
179
+ MAX_FRAMES_IN_FLIGHT = 2
180
+ image_available_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
181
+ render_finished_semaphores = MAX_FRAMES_IN_FLIGHT.times.map { device.create_semaphore }
182
+ in_flight_fences = MAX_FRAMES_IN_FLIGHT.times.map { device.create_fence signaled: true }
183
+ current_frame = 0
184
+ frame_counter = 0
185
+ start_time = Time.now
186
+ done = false
187
+
188
+ # Begin main event loop & drawing
189
+ until done
190
+ frame_counter += 1
191
+ break if ENV['MAX_FRAMES'].to_i == frame_counter
192
+ # dump some FPS infos
193
+ uptime = ENV['TIME_STEP'] ? ENV['TIME_STEP'].to_f * frame_counter : Time.now - start_time
194
+ if frame_counter % 3000 == 0
195
+ fps = frame_counter / uptime
196
+ p ['fps: ', fps, 'frame-time (ms): ', 1000.0 / fps]
197
+ end
198
+ while event = SDL2::Event.poll
199
+ case event
200
+ when SDL2::Event::Quit, SDL2::Event::KeyDown then done = true
201
+ when SDL2::Event::Window::RESIZED then rebuild_swap_chain.call
202
+ end
203
+ end
204
+
205
+ begin
206
+ in_flight_fences[current_frame].wait_and_reset
207
+ image_index = $swapchain.next_image_index(semaphore: image_available_semaphores[current_frame])
208
+ UniformBuffers[image_index].map do |data|
209
+ Mat4.identity $model_matrix
210
+ $model_matrix.rotate! Vec3.new([0, 0, 1]), uptime * 90.to_radians
211
+ Mat4.look_at Vec3.new([2, 2, 2]), Vec3.zero, Vec3.new([0, 0, 1]), $view_matrix
212
+ Mat4.perspective $projection_matrix, fovy: 45.to_radians,
213
+ aspect: $swapchain.width.to_f / $swapchain.height.to_f,
214
+ near: 0.1,
215
+ far: 10
216
+ $projection_matrix[1][1] *= -1
217
+ data[0, UniformBufferStruct.size] = $ubo[0, UniformBufferStruct.size]
218
+ end
219
+ graphics_queue.submit([$command_buffers[image_index]],
220
+ wait_semaphores: [image_available_semaphores[current_frame]],
221
+ wait_stages: [Vulkan::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
222
+ signal_semaphores: [render_finished_semaphores[current_frame]],
223
+ fence: in_flight_fences[current_frame])
224
+ presentation_queue.present(swapchains: [$swapchain],
225
+ image_indices: [image_index],
226
+ wait_semaphores: [render_finished_semaphores[current_frame]])
227
+ current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT
228
+ rescue Vulkan::Error
229
+ case $!.code
230
+ when Vulkan::VK_ERROR_OUT_OF_DATE_KHR, Vulkan::VK_SUBOPTIMAL_KHR
231
+ rebuild_swap_chain.call
232
+ else raise
233
+ end
234
+ end
235
+ end
236
+
237
+ in_flight_fences.each { |fence| fence.wait_and_reset }