{"id":13753722,"url":"https://github.com/adrien-ben/vulkan-tutorial-rs","last_synced_at":"2025-05-09T00:09:36.492Z","repository":{"id":38955005,"uuid":"170751733","full_name":"adrien-ben/vulkan-tutorial-rs","owner":"adrien-ben","description":"Vulkan tutorial written in Rust using Ash","archived":false,"fork":false,"pushed_at":"2025-04-07T12:35:40.000Z","size":15065,"stargazers_count":188,"open_issues_count":2,"forks_count":13,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-09T00:09:27.904Z","etag":null,"topics":["android","ash","rust","vulkan"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adrien-ben.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-14T20:12:51.000Z","updated_at":"2025-05-07T02:44:08.000Z","dependencies_parsed_at":"2024-04-02T12:41:04.754Z","dependency_job_id":"769fba47-0508-485b-b630-0816197055d2","html_url":"https://github.com/adrien-ben/vulkan-tutorial-rs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrien-ben%2Fvulkan-tutorial-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrien-ben%2Fvulkan-tutorial-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrien-ben%2Fvulkan-tutorial-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adrien-ben%2Fvulkan-tutorial-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adrien-ben","download_url":"https://codeload.github.com/adrien-ben/vulkan-tutorial-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253166521,"owners_count":21864482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","ash","rust","vulkan"],"created_at":"2024-08-03T09:01:28.244Z","updated_at":"2025-05-09T00:09:36.434Z","avatar_url":"https://github.com/adrien-ben.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Vulkan tutorial\n\n![][8]\n\nVulkan [tutorials][0] written in Rust using [Ash][1]. The [extended][10] branch contains a few more\nchapters that I won't merge on that branch since I want it to stay close to the original tutorial.\nPlease check it out :). If you wan't to run it on android see the [android][11] branch.\n\n![The end result](screenshots/end.png)\n\n## Introduction\n\nThis repository will follow the structure of the original tutorial. Each \ncommit will correspond to one page or on section of the page for \nlong chapters.\n\nSometimes an 'extra' commit will be added with some refactoring, commenting or feature.\n\nAll chapters of the original tutorial are now covered. The code compiles on windows, linux\nand macos and runs on windows, and linux. It should also run on macos but I haven't been\nable to test yet. I'll update this statement when I (or someone else) can try.\n\n## Requirements\n\nYou need to have a [Vulkan SDK][3] installed and  `glslangValidator` executable in your `PATH`. \nThis should be the case when installing the Vulkan SDK.\n\nIf for some reason you want to skip the shader compilation when buiding the project you can set\nthe `SKIP_SHADER_COMPILATION` environment variable to `true`. Though you will need to provide the\ncompiled shaders for the program to run.\n\n## Commits\n\nThis section contains the summary of the project commits. Follow :rabbit2: to go to the related \ntutorial page.\n\n### 1.1.1: Base code [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Base_code)\n\nApplication setup. We don't setup the window system now as it's done in \nthe original tutorial.\n\n### 1.1.2: Instance [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Instance)\n\nCreate and destroy the Vulkan instance with required surface extensions.\n\n### 1.1.3: Validation layers [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Validation_layers)\n\nAdd `VK_LAYER_LUNARG_standard_validation` at instance creation and creates\na debug report callback function after checking that it is available. \nSince we are using the `log` crate, we log the message with the proper log level.\nThe callback is detroyed at application termination.\n\n### 1.1.4: Physical devices and queue families [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Physical_devices_and_queue_families)\n\nFind a physical device with at least a queue family supporting graphics.\n\n### 1.1.5: Logical device and queues [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Logical_device_and_queues)\n\nCreate the logical device interfacing with the physical device. Then create\nthe graphics queue from the device.\n\n### 1.1.extra: Refactoring and comments\n\n- Update the readme with explanations on the structure of the repository. \n- Move validation layers related code to its own module.\n- Disabled validation layers on release build.\n\n### 1.2.1: Window surface [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Window_surface)\n\nCreate the window, the window surface and the presentation queue.\nUpdate the physical device creation to get a device with presentation support.\nAt that point, the code will only work on Windows.\n\n### 1.2.2: Swapchain [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Swap_chain)\n\nChecks for swapchain support and enable device extension for swapchain. Then\nquery the swapchain details and choose the right settings. Then create the \nswapchain and retrieve the swapchain images.\n\n### 1.2.3: Image views [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Image_views)\n\nCreate the image views to the swapchain images.\n\n### 1.2.extra: Refactoring swapchain creation\n\nAdd `SwapchainProperties` to hold the format, present mode and extent of our swapchain.\nAdd a method to build the best properties to `SwapchainSupportDetails`.\nMove these two struct into the `swapchain` module.\n\n### 1.3.2: Shader module [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Shader_modules)\n\nCreate the vertex and fragment shaders GLSL source and add a `compile.bat` script\nto compile it into SPIR-V bytecode using `glslangValidator`.\nLoad the compiled SPIR-V and create a `ShaderModule` from it.\n\nIn this section I forgot to create the shader stage create info structures. It's ok\nthey will be created in `1.3.5: Graphics pipeline`.\n\n### 1.3.3: Fixed functions [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Fixed_functions)\n\nThis one is huge so it will be split across several commits.\n\n- 1.3.3.1: Vertex input and input assembly\n\nCreate the vertex input and input assembly info for the pipeline.\n\n- 1.3.3.2: Viewports and scissors\n\nCreate the viewport and scissor info for the pipeline.\n\n- 1.3.3.3: Rasterizer\n\nCreate the rasterizer info for the pipeline.\n\n- 1.3.3.4: Multisampling\n\nCreate the multisampling info for the pipeline.\n\n- 1.3.3.5: Color blending\n\nCreate color blend attachment and color blend info for the pipeline.\n\n- 1.3.3.6: Pipeline layout\n\nCreate the pipeline layout info.\n\n### 1.3.4: Render passes [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Render_passes)\n\nCreate the render pass.\n\n### 1.3.5: Graphics pipeline [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Conclusion)\n\nCreate the `PipelineShaderStageCreateInfo` that we forgot in `1.3.2: Shader module`.\n\nCreate the grahics pipeline. \n\n### 1.3.extra: Shader compilation refactoring\n\nUntil now we compiled the shaders with a `compile.bat` script that we have to run \nmanually before running the application. In this section, we will compite them\nwhen building the application using [Cargo][2]'s build scripts.\n\nThe build script scan the content of the `shaders` directory and generates a compiled\nSPIR-V shader for each file it founds. The files are generated in a the same directory\nas the GLSL shaders and with the same name appended with `.spv`.\n\n### 1.4.1: Framebuffers [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Framebuffers)\n\nCreate one framebuffer for each image of the swapchain.\n\n### 1.4.2: Command buffers [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Command_buffers)\n\nCreate a command pool and allocate one command buffer per swapchain image.\nThen we register all the commands required to render.\n\n### 1.4.3: Rendering and presentation [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Rendering_and_presentation)\n\nThis section is also split across multiple commits.\n\n- 1.4.3.1: Main loop\n\nSetup the main loop.\n\n- 1.4.3.2: Semaphores\n\nCreate a semphore to signal that an image has been acquired and another one\nto signal that the rendering to the image is finished.\n\n- 1.4.3.3: Rendering the triangle!\n\nAcquire the next image from the swapchain, submit the command buffer and\npresent the rendered image.\n\n![The first triangle!](screenshots/triangle.png)\n\n- 1.4.3.4: Frames in flight\n\nLimit the number of frames that can be renderer simultaneously using fences.\n\n### 1.4.extra: Refactoring\n\n- Add `QueueFamilyIndices` structure and return it at physical device creation\nto avoid having to recreate it multiple times.\n- Add `SyncObjects` containing the semaphores and fence for one frame.\n- Add `InFlightFrames` containing all `SyncObjects` and the current frame index.\n- Implement `Iterator` for `InFlightFrames` so we just need to call `next()` to\nget next frame sync objects.\n\n### 1.5: Swapchain recreation [:rabbit2:](https://vulkan-tutorial.com/Drawing_a_triangle/Swap_chain_recreation)\n\nHandle swapchain recreation when resizing the window or when the swapchain is suboptimal\nor out of date.\n\n### 2.1: Vertex input description [:rabbit2:](https://vulkan-tutorial.com/Vertex_buffers/Vertex_input_description)\n\nRemove hard coded vertices from the vertex shader source and create vertices on the cpu.\nUpdate the pipeline with the vertex binding and attributes description.\n\n### 2.2: Vertex buffer creation [:rabbit2:](https://vulkan-tutorial.com/Vertex_buffers/Vertex_buffer_creation)\n\nCreate and fill the vertex buffer and bind it before rendering.\n\n### 2.3: Staging buffer [:rabbit2:](https://vulkan-tutorial.com/Vertex_buffers/Staging_buffer)\n\nCreate a staging buffer for the vertex data and copy the vertex data from this buffer's\nmemory to the memory of the device local buffer. \n\nThe tutorial also suggests that we allocate command buffers used for memory copy from\na command pool dedicated to short-lived command buffers, so we did that too.\n\n### 2.4: Index buffer [:rabbit2:](https://vulkan-tutorial.com/Vertex_buffers/Index_buffer)\n\nUse index buffer to reuse vertice when drawing a rectangle.\n\nIn the original tutorial the `create_index_buffer` is the same as `create_vertex_buffer`\nbut with the vertex data replaced with the index data. To limit duplication we've added\na method that creates and fill a buffer and fill it with the passed data. This method is\ncalled from `create_vertex_buffer` and `create_index_buffer`.\n\n![Then a quad.](screenshots/quad.png)\n\n### 3.1: Descriptor layout and buffer [:rabbit2:](https://vulkan-tutorial.com/Uniform_buffers/Descriptor_layout_and_buffer)\n\nCreate a `UniformBufferObject` structure containing transformation matrices and create the\ndescriptor layout and buffers used to make it accessible from the vertex shader.\n\nAlso add a `math` module containing a `perspective` function that creates a prespective matrix\nthat is working with Vulkan's NDC. \n\n### 3.2: Descriptor pool and sets [:rabbit2:](https://vulkan-tutorial.com/Uniform_buffers/Descriptor_pool_and_sets)\n\nCreate a descriptor pool and allocate a descriptor set for each descriptor buffer.\n\n![With MVP matrices.](screenshots/ubo.png)\n\n### 4.1: Images [:rabbit2:](https://vulkan-tutorial.com/Texture_mapping/Images)\n\nThis section is split too.\n\n- 4.1.1: Loading an image\n\nLoad an image from a file.\n\n- 4.1.2: Creating the image\n\nCreate an host visible staging buffer for image data and create a device local\nimage. At this point the image is empty, we will copy the buffer data in a later\nsection.\n\n- 4.1.3: Copying buffer data into the image\n\nCopy the image data store in the host visible buffer to the device local image.\n\n### 4.2: Image view and sampler [:rabbit2:](https://vulkan-tutorial.com/Texture_mapping/Image_view_and_sampler)\n\nCreate the image view and sampler. Also enable the sampler anisotropy feature.\n\n### 4.3: Combined image sampler [:rabbit2:](https://vulkan-tutorial.com/Texture_mapping/Combined_image_sampler)\n\nUpdate the descriptor set, add texture coordinates to `Vertex` and update the \nshaders to read texture coordinates and sample the texture.\n\n![Textured.](screenshots/texture.png)\n\n### 5: Depth buffering [:rabbit2:](https://vulkan-tutorial.com/Depth_buffering)\n\n Update `Vertex` to make the position 3d. Update the vertex shader to take the\n new dimension into account. Add a new quad to render. And setup depth buffer\n so the new quad is renderer correctly relatively to the other. Recreate the\n depth buffer resources when the swapchain is recreated.\n\n![With a friend!](screenshots/depth.png)\n\n### 5.extra: Refactoring\n\n Add `Texture` struct which will hold the resources required by mutable image,\n (image, memory, view and optionnally a sampler).\n\n Add `VkContext` that will hold the instance, debug callback, physical and logical\n devices, and surface.\n\n Overall refactoring of the code with some Rust specific code smell fixes.\n\n### 6: Loading models [:rabbit2:](https://vulkan-tutorial.com/Loading_models)\n\n Load a 3D model from an wavefront obj file and render it. We skip the deduplication\n step because the crate we use to load obj files already does it.\n\n### 6.extra: Orbital camera\n\nSince `3.1: Descriptor layout and buffer`, our rendered geometry has been spinning\ninfinitely around its local z axis. In this chapter we change this behaviour and\nimplement an orbital camera controlled with the mouse.\n\nYou can scroll the mouse wheel to get closer or further away from the global origin.\nAnd you can left click and move the mouse to move around the global origin.\n\n### 7: Generating mpimaps [:rabbit2:](https://vulkan-tutorial.com/Generating_Mipmaps)\n\nGenerate mipmaps for the model texture and update the sampler to make use of them.\n\n### 8: Multisampling [:rabbit2:](https://vulkan-tutorial.com/Multisampling)\n\nAdd multisampling anti-aliasing.\n\n![The end result](screenshots/end.png)\n\n## Run it\n\nWith validation layers:\n\n```sh\nRUST_LOG=vulkan_tutorial_ash=debug cargo run\n```\n\n\u003e The RUST_LOG level will affect the log level of the validation layers too.\n\nor without:\n\n```sh\ncargo run --release\n```\n\n## Links\n\n[Vulkan tutotial][0]\n\n[Ash][1]\n\n[Rust docs][4]\n\n[Cargo docs][2]\n\n[Vulkan SDK][3]\n\n[Vulkan specs][5]\n\n[The image statue][6]\n\n[The 3D model][7]\n\n## Credits\n\nThanks to Alexander Overvoorde for this amazing tutorials.\n\n[0]: https://vulkan-tutorial.com/Introduction\n[1]: https://github.com/MaikKlein/ash\n[2]: https://doc.rust-lang.org/cargo\n[3]: https://www.lunarg.com/vulkan-sdk\n[4]: https://doc.rust-lang.org/\n[5]: https://www.khronos.org/registry/vulkan/specs/1.1/html/\n[6]: https://pixabay.com/en/statue-sculpture-figure-1275469/\n[7]: https://sketchfab.com/3d-models/chalet-hippolyte-chassande-baroz-e925320e1d5744d9ae661aeff61e7aef\n[8]: https://github.com/adrien-ben/vulkan-tutorial-rs/workflows/Cross-platform%20build/badge.svg\n[10]: https://github.com/adrien-ben/vulkan-tutorial-rs/tree/extended\n[11]: https://github.com/adrien-ben/vulkan-tutorial-rs/tree/android\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadrien-ben%2Fvulkan-tutorial-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadrien-ben%2Fvulkan-tutorial-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadrien-ben%2Fvulkan-tutorial-rs/lists"}