### Import Vulkanalia Preludes for Vulkan Versions Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Shows how to import prelude modules from the vulkanalia crate to easily access commonly used Vulkan types and command traits. Examples are provided for Vulkan 1.0, 1.1, and 1.2. ```rust // Vulkan 1.0 use vulkanalia::prelude::v1_0::*; // Vulkan 1.1 use vulkanalia::prelude::v1_1::*; // Vulkan 1.2 use vulkanalia::prelude::v1_2::*; ``` -------------------------------- ### Rust Vulkanalia Prelude Imports Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Provides examples of how to import prelude modules in Rust for different Vulkan versions (1.0, 1.1, 1.2) to gain access to commonly used types and traits. ```rust \/ * Vulkan 1.0 *\/ use vulkanalia::prelude::v1_0 ::*; \/ * Vulkan 1.1 *\/ use vulkanalia::prelude::v1_1 ::*; \/ * Vulkan 1.2 *\/ use vulkanalia::prelude::v1_2 ::*; ``` -------------------------------- ### Vulkan Command Wrapper Example (C, C++, Rust) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Illustrates the usage of the Vulkan command vkEnumerateInstanceExtensionProperties across C, C++, and Rust. The C signature shows the raw function signature, while the C++ example demonstrates a typical multi-step C++ implementation. The Rust wrapper highlights how Vulkanalia simplifies this process, handling buffer allocation and error checking internally for more idiomatic and safer usage. ```c VkResult vkEnumerateInstanceExtensionProperties( const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties ); ``` ```cpp // 1. Call the command to get the number of extensions uint32_t pPropertyCount; vkEnumerateInstanceExtensionProperties(NULL, &pPropertyCount, NULL); // 2. Allocate a buffer that can contain the outputted number of extensions std::vector pProperties{pPropertyCount}; // 3. Call the command again to populate the buffer with the extensions vkEnumerateInstanceExtensionProperties(NULL, &pPropertyCount, pProperties.data()); ``` ```rust unsafe fn enumerate_instance_extension_properties( &self, layer_name: Option<&[u8]>, ) -> VkResult>; ``` -------------------------------- ### Rust: Basic Vulkan App Setup Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/base_code.md This snippet demonstrates the foundational Rust code for a Vulkan application. It initializes logging, creates a window and an event loop using the `winit` crate, and sets up a basic application structure with placeholder methods for creation, rendering, and destruction. It relies on `anyhow` for error handling. ```rust #![allow( dead_code, unused_variables, clippy::too_many_arguments, clippy::unnecessary_wraps )] use anyhow::Result; use winit::dpi::LogicalSize; use winit::event::{Event, WindowEvent}; use winit::event_loop::EventLoop; use winit::window::{Window, WindowBuilder}; fn main() -> Result<()> { pretty_env_logger::init(); // Window let event_loop = EventLoop::new()?; let window = WindowBuilder::new() .with_title("Vulkan Tutorial (Rust)") .with_inner_size(LogicalSize::new(1024, 768)) .build(&event_loop)?; // App let mut app = unsafe { App::create(&window)? }; event_loop.run(move |event, elwt| { match event { // Request a redraw when all events were processed. Event::AboutToWait => window.request_redraw(), Event::WindowEvent { event, .. } => match event { // Render a frame if our Vulkan app is not being destroyed. WindowEvent::RedrawRequested if !elwt.exiting() => unsafe { app.render(&window) }.unwrap(), // Destroy our Vulkan app. WindowEvent::CloseRequested => { elwt.exit(); unsafe { app.destroy(); } } _ => {} } _ => {} } })?; Ok(()) } /// Our Vulkan app. #[derive(Clone, Debug)] struct App {} impl App { /// Creates our Vulkan app. unsafe fn create(window: &Window) -> Result { Ok(Self {{}}) } /// Renders a frame for our Vulkan app. unsafe fn render(&mut self, window: &Window) -> Result<()> { Ok(()) } /// Destroys our Vulkan app. unsafe fn destroy(&mut self) {} } /// The Vulkan handles and associated properties used by our Vulkan app. #[derive(Clone, Debug, Default)] struct AppData {} ``` -------------------------------- ### Vulkan API Initialization Steps Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Outlines the fundamental steps for initializing the Vulkan API, from creating an instance to selecting hardware and configuring logical devices and queues. ```APIDOC Vulkan Initialization Process: 1. **Instance Creation (VkInstance)**: - Purpose: Initializes the Vulkan library and describes the application. - Configuration: Specify application details and required API extensions. - Functionality: Entry point for all Vulkan operations. 2. **Physical Device Selection (VkPhysicalDevice)**: - Purpose: Query and select available Vulkan-capable hardware. - Querying: Retrieve properties like VRAM size, device capabilities, and supported features. - Selection Criteria: Choose devices based on requirements (e.g., dedicated GPUs). 3. **Logical Device Creation (VkDevice)**: - Purpose: Create a logical representation of the selected physical device. - Configuration: Specify desired `VkPhysicalDeviceFeatures` (e.g., multi-viewport rendering, 64-bit floats). - Queue Families: Define which queue families to create queues from, enabling specific operations. 4. **Queue Allocation (VkQueue)**: - Purpose: Obtain handles to queues for submitting commands. - Queue Types: Queues are allocated from queue families, each supporting specific operations (e.g., graphics, compute, transfer). - Usage: Asynchronously execute operations by submitting commands to queues. ``` -------------------------------- ### Run Vulkan Cube Demo (Windows) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Executes the `vkcube.exe` demo from the Vulkan SDK installation directory. This verifies that Vulkan is properly installed and functional on the system. ```bash vkcube.exe ``` -------------------------------- ### Command Pool Creation Parameters Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/drawing/command_buffers.md Demonstrates the setup of `vk::CommandPoolCreateInfo`, specifically setting the queue family index required for command buffer allocation. ```rust let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?; let info = vk::CommandPoolCreateInfo::builder() .flags(vk::CommandPoolCreateFlags::empty()) // Optional. .queue_family_index(indices.graphics); ``` -------------------------------- ### C++ VkInstanceCreateInfo Population Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Demonstrates the manual C++ approach to populating a VkInstanceCreateInfo struct, which requires explicit setting of the sType field and enabledExtensionCount. ```c++ std::vector extensions{\/ * 3 extension names *\/}; VkInstanceCreateInfo info; info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; info.enabledExtensionCount = static_cast(extensions.size()); info.ppEnabledExtensionNames = extensions.data(); VkInstance instance; vkCreateInstance(&info, NULL, &instance); ``` -------------------------------- ### Install Vulkan Loader (Ubuntu) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Installs the Vulkan loader library on Ubuntu. The loader is responsible for finding and loading Vulkan implementations from graphics drivers at runtime. ```bash sudo apt install libvulkan-dev ``` -------------------------------- ### Install Vulkan Tools (Ubuntu) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Installs essential Vulkan command-line utilities on Ubuntu systems. This includes `vulkaninfo` for checking Vulkan capabilities and `vkcube` for testing Vulkan rendering. ```bash sudo apt install vulkan-tools ``` -------------------------------- ### Rust Vulkanalia Wrapper Signature Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Shows the idiomatic Rust wrapper signature for `vkEnumerateInstanceExtensionProperties` provided by Vulkanalia. This wrapper abstracts the multi-step process, handles optional parameters, and uses Rust's `Result` for error handling. ```rust unsafe fn enumerate_instance_extension_properties( &self, layer_name: Option<&[u8]>, ) -> VkResult>; ``` -------------------------------- ### Rust vk::InstanceCreateInfoBuilder Usage Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Shows the idiomatic Rust way to create a vk::InstanceCreateInfo using Vulkanalia's builder pattern, which automatically handles sType and counts, simplifying struct initialization. ```rust let extensions = &[\/ * 3 extension names *\/]; let info = vk::InstanceCreateInfo::builder() .enabled_extension_names(extensions) .build(); let instance = entry.create_instance(&info, None).unwrap(); ``` -------------------------------- ### Vulkanalia Command Wrapper Organization Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Explains how Vulkanalia organizes command wrappers into version and extension traits. This structure allows for clear separation of commands based on Vulkan versions and extensions, making them accessible via specific types like `Entry`, `Instance`, and `Device`. ```APIDOC Vulkanalia Command Wrapper Traits: - **Version Traits**: Group commands standard to specific Vulkan versions (e.g., `vk::EntryV1_0` for `vkEnumerateInstanceExtensionProperties`). - **Extension Traits**: Group commands defined in Vulkan extensions (e.g., `vk::KhrSurfaceExtension` for `destroy_surface_khr`). These traits are implemented for core Vulkanalia types: - `Entry`: Provides access to instance-level commands. - `Instance`: Provides access to instance-level commands, often requiring an instance handle. - `Device`: Provides access to device-level commands, requiring a device handle. Example Command Grouping: - `vk::EntryV1_0` trait: - `enumerate_instance_extension_properties`: Wraps `vkEnumerateInstanceExtensionProperties`. - `vk::DeviceV1_2` trait: - `cmd_draw_indirect_count`: Wraps `vkCmdDrawIndirectCount` (added in Vulkan 1.2, requires a device). - `vk::KhrSurfaceExtension` trait: - `destroy_surface_khr`: Wraps `vkDestroySurfaceKHR` (part of `VK_KHR_surface` extension). ``` -------------------------------- ### Store Swapchain Format and Extent Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Assigns the selected surface format and swapchain extent to the corresponding fields within the `AppData` struct. These values are determined during the swapchain creation process and are necessary for subsequent rendering setup. ```rust data.swapchain_format = surface_format.format; data.swapchain_extent = extent; ``` -------------------------------- ### Physical Device Extension Check Setup Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Sets up the `check_physical_device` function to call a new `check_physical_device_extensions` function. This structure allows for modular checking of physical device capabilities, including extension support. ```rust unsafe fn check_physical_device( instance: &Instance, data: &AppData, physical_device: vk::PhysicalDevice, ) -> Result<()> { QueueFamilyIndices::get(instance, data, physical_device)?; check_physical_device_extensions(instance, physical_device)?; Ok(()) } unsafe fn check_physical_device_extensions( instance: &Instance, physical_device: vk::PhysicalDevice, ) -> Result<()> { Ok(()) } ``` -------------------------------- ### Create Rust Cargo Project Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Initializes a new Rust project using Cargo. This command creates a directory with a basic project structure, including a `Cargo.toml` file and a `src` directory for source code. ```bash cargo new vulkan-tutorial ``` -------------------------------- ### Rust Builder Lifetime Example (Potentially Unsafe) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Illustrates a Rust code pattern that could lead to a crash due to temporary value lifetimes being dropped before use. Vulkanalia's design prevents this by allowing builders to be passed directly to command wrappers. ```rust let info = vk::InstanceCreateInfo::builder() .enabled_extension_names(&vec![\/ * 3 extension names *\/]) .build(); let instance = entry.create_instance(&info, None).unwrap(); ``` -------------------------------- ### Vulkan Main Rendering Loop Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md The main loop acquires an image from the swapchain, selects the appropriate command buffer for that image, and submits it for execution using vkQueueSubmit. The image is then returned to the swapchain for presentation via vkQueuePresentKHR. Synchronization using semaphores is crucial for correct execution order. ```Vulkan API Acquire image from swapchain: vkAcquireNextImageKHR Submit command buffer: vkQueueSubmit Present image to swapchain: vkQueuePresentKHR ``` -------------------------------- ### Setup Vulkan Environment Script Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Sources the Vulkan SDK environment setup script to ensure Vulkan libraries are found when running applications outside the SDK directory. ```shell source ~/VulkanSDK/1.3.280.1/setup-env.sh ``` -------------------------------- ### Simplify Vulkan Struct Creation with Vulkanalia Builders Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Demonstrates using vulkanalia's builder pattern to construct Vulkan structs like vk::InstanceCreateInfo. It highlights automatic sType and count field management and the importance of lifetime management when using builders. ```rust let extensions = &[ /* 3 extension names */ ]; let info = vk::InstanceCreateInfo::builder() .enabled_extension_names(extensions) .build(); let instance = entry.create_instance(&info, None).unwrap(); ``` -------------------------------- ### Create Vulkan Graphics Pipeline Function Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/pipeline/introduction.md This snippet demonstrates the integration of a `create_pipeline` function within the `App::create` method in Rust. It shows the function signature and its placement after `create_swapchain_image_views`, indicating its role in setting up the Vulkan graphics pipeline. ```rust impl App { unsafe fn create(window: &Window) -> Result { // ... create_swapchain_image_views(&device, &mut data)?; create_pipeline(&device, &mut data)?; // ... } } unsafe fn create_pipeline(device: &Device, data: &mut AppData) -> Result<()> { Ok(()) } ``` -------------------------------- ### Build Vulkan Render Pass Begin Info (Rust) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/drawing/command_buffers.md Constructs the `vk::RenderPassBeginInfo` structure, which contains essential parameters for starting a render pass. It links the render pass, framebuffer, render area, and clear values, preparing the command buffer for rendering operations. ```rust let clear_values = &[color_clear_value]; let info = vk::RenderPassBeginInfo::builder() .render_pass(data.render_pass) .framebuffer(data.framebuffers[i]) .render_area(render_area) .clear_values(clear_values); ``` -------------------------------- ### Example Device Suitability Logic Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/physical_devices_and_queue_families.md Provides a concrete implementation of `check_physical_device` that enforces requirements for discrete GPUs and the presence of geometry shader support, returning specific `SuitabilityError` messages if criteria are not met. ```Rust unsafe fn check_physical_device( instance: &Instance, data: &AppData, physical_device: vk::PhysicalDevice, ) -> Result<()> { let properties = instance.get_physical_device_properties(physical_device); if properties.device_type != vk::PhysicalDeviceType::DISCRETE_GPU { return Err(anyhow!(SuitabilityError("Only discrete GPUs are supported."))); } let features = instance.get_physical_device_features(physical_device); if features.geometry_shader != vk::TRUE { return Err(anyhow!(SuitabilityError("Missing geometry shader support."))); } Ok(()) } ``` -------------------------------- ### Run Vulkan Cube Demo (Linux) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Executes the `vkcube` command-line utility to test Vulkan rendering capabilities. This command should display a rotating cube if Vulkan is correctly set up. ```bash vkcube ``` -------------------------------- ### Update AppData with Swapchain Details Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Expands the `AppData` struct to include fields for `swapchain_format`, `swapchain_extent`, and the `swapchain` handle itself, in addition to the `swapchain_images`. These details are vital for configuring rendering targets and presentation. ```rust struct AppData { // ... swapchain_format: vk::Format, swapchain_extent: vk::Extent2D, swapchain: vk::SwapchainKHR, swapchain_images: Vec, } ``` -------------------------------- ### Integrate vk_window::create_surface Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/window_surface.md Illustrates integrating the `vk_window::create_surface` function into the application's setup. This function abstracts platform-specific surface creation details, making it easier to handle different windowing systems. ```rust unsafe fn create(window: &Window) -> Result { // ... let instance = create_instance(window, &entry, &mut data)?; data.surface = vk_window::create_surface(&instance, &window, &window)?; pick_physical_device(&instance, &mut data)?; // ... } ``` -------------------------------- ### Vulkan: Transition Image Layout Function Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/texture/images.md A placeholder function for transitioning an image's layout. It uses single-time command buffer helpers but requires further implementation for actual barrier setup. ```rust unsafe fn transition_image_layout( device: &Device, data: &AppData, image: vk::Image, format: vk::Format, old_layout: vk::ImageLayout, new_layout: vk::ImageLayout, ) -> Result<()> { let command_buffer = begin_single_time_commands(device, data)?; // TODO: Implement actual image memory barrier setup here // device.cmd_pipeline_barrier(...) end_single_time_commands(device, data, command_buffer)?; Ok(()) } ``` -------------------------------- ### Get Required Vulkan Instance Extensions Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/instance.md Enumerates the global Vulkan extensions required for window rendering using Vulkanalia's window integration. These extensions are converted into null-terminated C strings for Vulkan API usage. ```rust let extensions = vk_window::get_required_instance_extensions(window) .iter() .map(|e| e.as_ptr()) .collect::>(); ``` -------------------------------- ### Vulkan Command Loading and Categories Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md vulkanalia defines type aliases for Vulkan function pointers (e.g., PFN_vkCreateInstance) and provides structs to manage the loading of Vulkan commands. Commands are categorized based on their loading context: StaticCommands for platform-specific initial loading, EntryCommands for instance-independent commands, InstanceCommands for instance-specific commands, and DeviceCommands for device-specific commands. ```APIDOC Vulkan Function Pointer Type Aliases: - Defined with the PFN_ prefix, e.g., vk::PFN_vkCreateInstance for vkCreateInstance. Vulkan Command Loading: - vkGetInstanceProcAddr: Loads commands using a platform-specific method, used to load other commands. - vkGetDeviceProcAddr: Loads device-specific commands to avoid runtime dispatch overhead. Command Categories (Structs in vulkanalia): - vk::StaticCommands: - Description: Vulkan commands loaded in a platform-specific manner, used to load other commands (e.g., vkGetInstanceProcAddr, vkGetDeviceProcAddr). - Related: vkGetInstanceProcAddr, vkGetDeviceProcAddr. - vk::EntryCommands: - Description: Vulkan commands loaded using vkGetInstanceProcAddr with a null Vulkan instance. Used for querying instance support and creating instances. - Related: vkGetInstanceProcAddr. - vk::InstanceCommands: - Description: Vulkan commands loaded using vkGetInstanceProcAddr with a valid Vulkan instance. Tied to a specific instance, used for querying device support and creating devices. - Related: vkGetInstanceProcAddr. - vk::DeviceCommands: - Description: Vulkan commands loaded using vkGetDeviceProcAddr with a valid Vulkan device. Tied to a specific device, expose most graphics API functionality. - Related: vkGetDeviceProcAddr. ``` -------------------------------- ### Vulkan API Definition and Vulkanalia Interface Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md The Vulkan API is defined in C and its canonical definition resides in an XML file. Vulkanalia provides a Rust interface generated from this registry, independent of the C SDK headers. The foundation is the 'vulkanalia-sys' crate for raw types, re-exported by the 'vulkanalia' crate. ```APIDOC Vulkan API Concepts: - Canonical definition: Vulkan API Registry (XML file). - Vulkan Headers: Generated from registry, part of Vulkan SDK. - Vulkanalia Interface: - Built on 'vulkanalia-sys' crate for raw types (commands, enums, structs). - 'vulkanalia' crate re-exports raw types via the 'vk' module. - Provides a Rust interface generated from the Vulkan API Registry. - Independent of the C interface provided by the Vulkan SDK. ``` -------------------------------- ### Vulkan Drawing Operations Recording Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/overview.md Operations like drawing must be recorded into a VkCommandBuffer, which is allocated from a VkCommandPool associated with a queue family. This involves beginning a render pass, binding a pipeline, issuing draw calls, and ending the render pass. Command buffers are recorded per swapchain image for efficiency. ```Vulkan API Begin the render pass Bind the graphics pipeline Draw 3 vertices End the render pass ``` -------------------------------- ### Install Vulkan Validation Layers (Ubuntu) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Installs the standard Vulkan validation layers on Ubuntu. These layers are critical for debugging Vulkan applications by detecting common errors and providing helpful diagnostics. ```bash sudo apt install vulkan-validationlayers-dev ``` -------------------------------- ### Create Vulkan Instance: Instance Creation Info Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/instance.md Constructs the `vk::InstanceCreateInfo` struct, enabling the previously enumerated extensions and linking the application info. It then uses the Vulkan entry point to create the instance. ```rust let info = vk::InstanceCreateInfo::builder() .application_info(&application_info) .enabled_extension_names(&extensions); Ok(entry.create_instance(&info, None)?) ``` -------------------------------- ### App::create Method: Initialize Vulkan Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/instance.md Initializes the Vulkan entry point by loading the Vulkan shared library and then creates the Vulkan instance using the `create_instance` function. This method populates the `App` struct with these essential Vulkan objects. ```rust unsafe fn create(window: &Window) -> Result { let loader = LibloadingLoader::new(LIBRARY)?; let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?; let instance = create_instance(window, &entry)?; Ok(Self { entry, instance }) } ``` -------------------------------- ### Add start field to App struct Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/uniform/descriptor_set_layout_and_buffer.md Adds a `start` field of type `Instant` to the `App` struct. This field will store the time when the application was created, allowing for calculations of elapsed time. ```rust struct App { // ... start: Instant, } ``` -------------------------------- ### Rust QueueFamilyIndices Struct and Get Method Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/physical_devices_and_queue_families.md Defines a struct to store indices of required queue families, specifically the graphics queue. The `get` method iterates through physical device queue properties to find a family supporting graphics operations, returning an error if none is found. It requires `Instance`, `AppData`, and `vk::PhysicalDevice` as inputs. ```rust #[derive(Copy, Clone, Debug)] struct QueueFamilyIndices { graphics: u32, } impl QueueFamilyIndices { unsafe fn get( instance: &Instance, data: &AppData, physical_device: vk::PhysicalDevice, ) -> Result { let properties = instance .get_physical_device_queue_family_properties(physical_device); let graphics = properties .iter() .position(|p| p.queue_flags.contains(vk::QueueFlags::GRAPHICS)) .map(|i| i as u32); if let Some(graphics) = graphics { Ok(Self { graphics }) } else { Err(anyhow!(SuitabilityError("Missing required queue families."))) } } } ``` -------------------------------- ### Begin Vulkan Command Buffer Recording Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/drawing/command_buffers.md Shows how to begin recording commands into a Vulkan command buffer. This involves creating a `vk::CommandBufferBeginInfo` structure to specify usage details and calling the `begin_command_buffer` method. ```Rust for (i, command_buffer) in data.command_buffers.iter().enumerate() { let inheritance = vk::CommandBufferInheritanceInfo::builder(); let info = vk::CommandBufferBeginInfo::builder() .flags(vk::CommandBufferUsageFlags::empty()) // Optional. .inheritance_info(&inheritance); // Optional. device.begin_command_buffer(*command_buffer, &info)?; } ``` -------------------------------- ### Build Vulkan Device Creation Info Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/logical_device_and_queues.md Constructs the vk::DeviceCreateInfo structure, specifying queue creation information, enabled layers, extensions, and features required for the logical device. ```rust let queue_infos = &[queue_info]; let info = vk::DeviceCreateInfo::builder() .queue_create_infos(queue_infos) .enabled_layer_names(&layers) .enabled_extension_names(&extensions) .enabled_features(&features); ``` -------------------------------- ### Create ImageViewCreateInfo and Image View Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/image_views.md Constructs the `vk::ImageViewCreateInfo` struct with the image handle, format, component mapping, and subresource range. Then, it calls `device.create_image_view` to create the actual Vulkan image view. ```rust let info = vk::ImageViewCreateInfo::builder() .image(*i) .view_type(vk::ImageViewType::_2D) .format(data.swapchain_format) .components(components) .subresource_range(subresource_range); device.create_image_view(&info, None) ``` -------------------------------- ### Initialize Swapchain Image Tracking Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/drawing/rendering_and_presentation.md Initializes the `images_in_flight` vector with null fences, indicating that no frame is currently using any swapchain image at the start. ```rust unsafe fn create_sync_objects(device: &Device, data: &mut AppData) -> Result<()> { // ... data.images_in_flight = data.swapchain_images .iter() .map(|_| vk::Fence::null()) .collect(); Ok(()) } ``` -------------------------------- ### Map Swapchain Images to Image Views Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/image_views.md Iterates over the swapchain images and prepares to create a `vk::ImageView` for each one. This involves mapping the raw image handles to view configurations. ```rust unsafe fn create_swapchain_image_views( device: &Device, data: &mut AppData, ) -> Result<()> { data.swapchain_image_views = data .swapchain_images .iter() .map(|i| { // ImageView creation logic will go here }) .collect::, _>>()?; Ok(()) } ``` -------------------------------- ### Creating the Command Pool Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/drawing/command_buffers.md Shows the actual Vulkan API call to create a command pool using the configured `vk::CommandPoolCreateInfo`. ```rust data.command_pool = device.create_command_pool(&info, None)?; ``` -------------------------------- ### Get Depth Format Helper Function Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/model/depth_buffering.md A specialized function that uses `get_supported_format` to find an optimal format suitable for depth attachments, prioritizing common formats like D32_SFLOAT. ```rust unsafe fn get_depth_format(instance: &Instance, data: &AppData) -> Result { let candidates = &[ vk::Format::D32_SFLOAT, vk::Format::D32_SFLOAT_S8_UINT, vk::Format::D24_UNORM_S8_UINT, ]; get_supported_format( instance, data, candidates, vk::ImageTiling::OPTIMAL, vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT, ) } ``` -------------------------------- ### Configure Logical Device Creation with Queue Infos Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/window_surface.md Configures the `vk::DeviceCreateInfo` builder to include the prepared queue creation information. This step is crucial for Vulkan to create the logical device with the necessary queues. ```rust let info = vk::DeviceCreateInfo::builder() .queue_create_infos(&queue_infos) .enabled_layer_names(&layers) .enabled_extension_names(&extensions) .enabled_features(&features); ``` -------------------------------- ### Configure Stencil Operations Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/model/depth_buffering.md Configures stencil buffer operations for front and back faces. This functionality is not used in this example and requires the depth/stencil image format to include a stencil component. ```rust .stencil_test_enable(false) .front(/* vk::StencilOpState */) // Optional. .back(/* vk::StencilOpState */); ``` -------------------------------- ### Configure Depth Bounds Test Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/model/depth_buffering.md Configures optional depth bounds testing, which limits fragment retention to a specified depth range (min_depth_bounds to max_depth_bounds). This functionality is disabled in this example. ```rust .depth_bounds_test_enable(false) .min_depth_bounds(0.0) // Optional. .max_depth_bounds(1.0) // Optional. ``` -------------------------------- ### Vulkan Shader Compilation Tools (Windows) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/development_environment.md Identifies command-line tools provided by the Vulkan SDK for compiling GLSL shaders into bytecode. `glslangValidator.exe` and `glslc.exe` are used for this purpose. ```bash glslangValidator.exe glslc.exe ``` -------------------------------- ### Create Depth Objects Function Signature Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/model/depth_buffering.md Declares the `create_depth_objects` function, responsible for initializing the depth image, memory, and view. It's typically called during application setup after command pool creation. ```rust unsafe fn create_depth_objects( instance: &Instance, device: &Device, data: &mut AppData, ) -> Result<()> { Ok(()) } ``` -------------------------------- ### Rust Depth Buffering Implementation Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/model/depth_buffering.md The main Rust code for implementing depth buffering. This file handles the application logic, Vulkan setup, and rendering pipeline configuration related to depth testing. ```rust /* Code for main.rs not provided in the input text. */ /* Please provide the actual Rust code for this snippet. */ ``` -------------------------------- ### vulkanalia Instance vs vk::Instance Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/instance.md Explains the distinction between vulkanalia's custom `Instance` type and the raw Vulkan `vk::Instance` handle. The `vulkanalia::Instance` type bundles the raw handle with loaded commands, simplifying usage. ```APIDOC vulkanalia::Instance vs vk::Instance - `vulkanalia::Instance`: A custom type provided by the vulkanalia library. It encapsulates both the raw Vulkan instance handle (`vk::Instance`) and the Vulkan commands loaded specifically for that instance. - **Benefit**: Simplifies command usage by automatically providing the necessary instance handle. - **Example**: The `destroy_instance` method on `vulkanalia::Instance` only requires allocator callbacks, as it internally uses the raw Vulkan instance handle. - `vk::Instance`: The standard, raw Vulkan instance handle as defined by the Vulkan API. - **Usage**: Typically requires explicit passing of the instance handle to Vulkan commands (e.g., `vkDestroyInstance`). - **Note**: Developers using vulkanalia directly will interact more with `vulkanalia::Instance` and less with `vk::Instance`. ``` -------------------------------- ### Create Swapchain Image Views Function Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/image_views.md Defines the signature for the `create_swapchain_image_views` function and shows its call after swapchain creation in the application's initialization. ```rust impl App { unsafe fn create(window: &Window) -> Result { // ... create_swapchain(window, &instance, &device, &mut data)?; create_swapchain_image_views(&device, &mut data)?; // ... } } unsafe fn create_swapchain_image_views( device: &Device, data: &mut AppData, ) -> Result<()> { Ok(()) } ``` -------------------------------- ### Call create_framebuffers in App::create Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/drawing/framebuffers.md Shows where the `create_framebuffers` function is called within the `App::create` method. This integrates framebuffer creation into the application's setup process after the graphics pipeline is created. ```rust impl App { unsafe fn create(window: &Window) -> Result { // ... create_pipeline(&device, &mut data)?; create_framebuffers(&device, &mut data)?; // ... } } ``` -------------------------------- ### Vulkanalia Rust Imports Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/instance.md Imports necessary crates and modules for Vulkan initialization, including logging, error handling, Vulkanalia loader, window integration, and the Vulkan 1.0 prelude. ```rust use anyhow::{anyhow, Result}; use log::*; use vulkanalia::loader::{LibloadingLoader, LIBRARY}; use vulkanalia::window as vk_window; use vulkanalia::prelude::v1_0::*; ``` -------------------------------- ### Calculate elapsed time in update_uniform_buffer Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/uniform/descriptor_set_layout_and_buffer.md Calculates the time elapsed since the application started using `self.start.elapsed()`. The result is converted to seconds as a floating-point number (`f32`) for use in transformations. ```rust unsafe fn update_uniform_buffer(&self, image_index: usize) -> Result<()> { let time = self.start.elapsed().as_secs_f32(); Ok(()) } ``` -------------------------------- ### Vulkan: Image Subresource Range Configuration Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/texture/images.md Defines the specific parts of a Vulkan image that a memory barrier or other image operations will affect. This example configures it for a non-array, non-mipmapped color image. ```rust let subresource = vk::ImageSubresourceRange::builder() .aspect_mask(vk::ImageAspectFlags::COLOR) .base_mip_level(0) .level_count(1) .base_array_layer(0) .layer_count(1); ``` -------------------------------- ### Rust: App Initialization with Texture Image Creation Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/texture/images.md Demonstrates calling the `create_texture_image` function after creating the command pool during application initialization. This ensures resources are set up in the correct order. ```rust impl App { unsafe fn create(window: &Window) -> Result { // ... create_command_pool(&instance, &device, &mut data)?; create_texture_image(&instance, &device, &mut data)?; // ... } } unsafe fn create_texture_image( instance: &Instance, device: &Device, data: &mut AppData, ) -> Result<()> { Ok(()) } ``` -------------------------------- ### Query Swapchain Support Details Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Implements a method `SwapchainSupport::get` to query Vulkan for swapchain details. It retrieves surface capabilities, supported formats, and available presentation modes for a given physical device and surface. Requires Vulkan instance and app data. ```rust impl SwapchainSupport { unsafe fn get( instance: &Instance, data: &AppData, physical_device: vk::PhysicalDevice, ) -> Result { Ok(Self { capabilities: instance .get_physical_device_surface_capabilities_khr( physical_device, data.surface)?, formats: instance .get_physical_device_surface_formats_khr( physical_device, data.surface)?, present_modes: instance .get_physical_device_surface_present_modes_khr( physical_device, data.surface)?, }) } } ``` -------------------------------- ### Determine Swapchain Image Count Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Calculates the optimal number of images for the swapchain. It starts with the minimum required by the driver and adds one to prevent waiting, while also respecting the maximum image count if specified. ```rust let mut image_count = support.capabilities.min_image_count + 1; if support.capabilities.max_image_count != 0 && image_count > support.capabilities.max_image_count { image_count = support.capabilities.max_image_count; } ``` -------------------------------- ### Define Component Mapping for Image Views Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/image_views.md Configures how color channels (R, G, B, A) are mapped for the image view. This example uses identity mapping, preserving the original channel values. ```rust let components = vk::ComponentMapping::builder() .r(vk::ComponentSwizzle::IDENTITY) .g(vk::ComponentSwizzle::IDENTITY) .b(vk::ComponentSwizzle::IDENTITY) .a(vk::ComponentSwizzle::IDENTITY); ``` -------------------------------- ### Transition Image Layout and Copy Buffer to Image Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/texture/images.md Demonstrates transitioning a Vulkan image layout to `TRANSFER_DST_OPTIMAL` and then copying data from a staging buffer to the texture image. Requires `transition_image_layout` and `copy_buffer_to_image` functions. ```rust transition_image_layout( device, data, data.texture_image, vk::Format::R8G8B8A8_SRGB, vk::ImageLayout::UNDEFINED, vk::ImageLayout::TRANSFER_DST_OPTIMAL, )?; copy_buffer_to_image( device, data, staging_buffer, data.texture_image, width, height, )?; ``` -------------------------------- ### Vulkan Swapchain Presentation Functions Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/swapchain/recreation.md Details the Vulkan functions involved in swapchain image acquisition and presentation, and their relevant return codes for handling swapchain status changes. ```APIDOC vk::Device::acquire_next_image_khr - Purpose: Acquires the next available swapchain image for rendering. - Return Values: - Ok((image_index, timeout_elapsed)): Successfully acquired image index. - Err(vk::ErrorCode::OUT_OF_DATE_KHR): Swapchain is out of date. - Err(other_error): Other Vulkan error. vk::Device::queue_present_khr - Purpose: Presents the swapchain image to the surface. - Parameters: - queue: The presentation queue. - present_info: Structure containing swapchain and image index information. - Return Values: - Ok(vk::SuccessCode::SUBOPTIMAL_KHR): Swapchain is suboptimal but presentation succeeded. - Err(vk::ErrorCode::OUT_OF_DATE_KHR): Swapchain is out of date. - Err(other_error): Other Vulkan error. ``` -------------------------------- ### Vulkan Initialization and Device Selection Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/setup/physical_devices_and_queue_families.md Demonstrates the integration of physical device selection into the application's creation process and defines a custom error type for device suitability checks using the `thiserror` crate. ```Rust use thiserror::Error; impl App { unsafe fn create(window: &Window) -> Result { // ... pick_physical_device(&instance, &mut data)?; Ok(Self { entry, instance, data }) } } #[derive(Debug, Error)] #[error("Missing {0}.")] pub struct SuitabilityError(pub &'static str); unsafe fn pick_physical_device(instance: &Instance, data: &mut AppData) -> Result<()> { Ok(()) } ``` -------------------------------- ### Compile GLSL Shaders on macOS Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/pipeline/shader_modules.md Shell script to compile GLSL shader files into SPIR-V bytecode using glslc on macOS. Users must replace the placeholder path with their Vulkan SDK installation path. ```bash /Users/user/VulkanSDK/x.x.x.x/macOS/bin/glslc shaders/shader.vert -o vert.spv /Users/user/VulkanSDK/x.x.x.x/macOS/bin/glslc shaders/shader.frag -o frag.spv ``` -------------------------------- ### Begin Vulkan Render Pass (Rust) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/drawing/command_buffers.md Initiates a Vulkan render pass by recording the `cmd_begin_render_pass` command into the command buffer. This function takes the render pass configuration and specifies how drawing commands will be provided, either inline or via secondary command buffers. ```rust device.cmd_begin_render_pass( *command_buffer, &info, vk::SubpassContents::INLINE); ``` -------------------------------- ### Create Unique Queue Family Info for Logical Device Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/window_surface.md Prepares `vk::DeviceQueueCreateInfo` structures for logical device creation. It identifies unique queue family indices (graphics and present) and sets queue priorities, ensuring efficient queue creation. ```rust let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?; let mut unique_indices = HashSet::new(); unique_indices.insert(indices.graphics); unique_indices.insert(indices.present); let queue_priorities = &[1.0]; let queue_infos = unique_indices .iter() .map(|i| { vk::DeviceQueueCreateInfo::builder() .queue_family_index(*i) .queue_priorities(queue_priorities) }) .collect::>(); ``` -------------------------------- ### Bash: Compile GLSL Shaders on Windows Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/pipeline/shader_modules.md This batch script compiles GLSL shader files (`.vert`, `.frag`) into SPIR-V bytecode using `glslc.exe`. It requires the Vulkan SDK to be installed and the path to `glslc.exe` to be correctly set. ```bash C:/VulkanSDK/x.x.x.x/Bin32/glslc.exe shader.vert -o vert.spv C:/VulkanSDK/x.x.x.x/Bin32/glslc.exe shader.frag -o frag.spv pause ``` -------------------------------- ### Initialize SwapchainCreateInfoKHR (Surface) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Begins the initialization of the `vk::SwapchainCreateInfoKHR` structure by setting the target Vulkan surface. This is a fundamental step in defining the swapchain's properties. ```rust let info = vk::SwapchainCreateInfoKHR::builder() .surface(data.surface) // continued... ``` -------------------------------- ### Get Supported Format Function Signature Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/model/depth_buffering.md Defines a generic function to find a suitable Vulkan format based on candidate lists, tiling mode, and required features. This is crucial for selecting formats like depth or stencil attachments. ```rust unsafe fn get_supported_format( instance: &Instance, data: &AppData, candidates: &[vk::Format], tiling: vk::ImageTiling, features: vk::FormatFeatureFlags, ) -> Result { candidates .iter() .cloned() .find(|f| { // Logic to check format support based on tiling and features }) .ok_or_else(|| anyhow!("Failed to find supported format!")) } ``` -------------------------------- ### Enable Swapchain Device Extension Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Modifies the `create_logical_device` function to enable the `VK_KHR_SWAPCHAIN_EXTENSION`. This involves preparing a list of extension names, including the swapchain extension, to be passed during logical device creation. ```rust let mut extensions = DEVICE_EXTENSIONS .iter() .map(|n| n.as_ptr()) .collect::>(); ``` -------------------------------- ### Describe Vulkan Subpass (Rust) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/pipeline/render_passes.md Constructs a `vk::SubpassDescription` to define a rendering operation within a render pass. This example specifies that it's a graphics subpass and links it to the previously defined color attachment reference. ```rust let color_attachments = &[color_attachment_ref]; let subpass = vk::SubpassDescription::builder() .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) .color_attachments(color_attachments); ``` -------------------------------- ### Retrieve Swapchain Images Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Retrieves the `vk::Image` handles associated with the created swapchain using the Vulkan device. The retrieved handles are stored in the `AppData` structure. This operation is typically performed after successful swapchain creation. ```rust data.swapchain_images = device.get_swapchain_images_khr(data.swapchain)?; ``` -------------------------------- ### Initialize SwapchainCreateInfoKHR (Image Details) Source: https://github.com/kylemayes/vulkanalia/blob/master/tutorial/book/src/presentation/swapchain.md Continues the initialization of `vk::SwapchainCreateInfoKHR` by specifying image properties such as count, format, color space, extent, array layers, and usage flags. ```rust .min_image_count(image_count) .image_format(surface_format.format) .image_color_space(surface_format.color_space) .image_extent(extent) .image_array_layers(1) .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) ```