`VkInstance` - application and extensions - `VkPhysicalDevice` - selected based on properties and capabilities - `VkDevice` (also known as a logical device), describes which `VkPhysicalDeviceFeatures` will be used, which queue families - `VkQueue`, allocated from queue families, examples of families are graphics, compute, and memory transfer - `VkSurfaceKHR`, a window surface, it's an extension that provides ways to interact with the window manager, in our case GLFW will handle the specific details. - `VkSwapchainKHR`, a swap chain, it's a collection of targets for rendering. its first purpose is ensuring that the image that is being rendered is not the same one that is on the screen, the most common ways to use one are double and triple buffering, swapchains provide images. - On some platforms there are extensions (`VK_KHR_display`, `VK_KHR_display_swapchain`) that allow one to draw to the entire screen. - Once an image is obtained from the swapchain it has to be wrapped into: - `VkImageView`, an image view references a specific part of an image to be used - `VkFramebuffer`, a framebuffer references images that are used for color, depth, and stencil targets. in these examples the image views and framebuffers for each image in the swapchain will be created ahead of time. - Render passes describe the type of images that are used during rendering, their usage, and how their content will be treated, to draw a simple triangle we can tell vulkan that there will be a single image that's a color target and that it needs to be cleared to a solid color before drawing. Note: a render pass describes the type of images, a `VkFramebuffer` binds specific images to slots. Render passes have subpasses, while a render pass describes which images are going to be used the subpasses describe which ones will be used for what. - `VkPipeline`, describes the configuration of the graphics card, like viewport size, depth buffer operations, the programmable state is specified using `VkShaderModule` objects, which are created from shader bytecode. The driver also needs to know which render targets are going to be used in the pipeline. All of the settings are configured in advance, and changing them requires creating a new `VkPipeline`. Each pipeline is bound to a compatible render pass to it, at a specific subpass of it, the reason for this is twofold: things such as fragment shaders will end up writing to the attachments, so it makes sense that a pipeline, which among other things holds shaders, should know which ones and how, secondarily this allows for optimizations on tiled gpus, which are sometimes able to merge subpasses. Another important details is that as of later versions of vulkan render passes are not required when enabling an extension (`VK_KHR_dynamic_rendering`), this simplifies the code at the potential cost of performance on some hardware. - Commands are recorded into a `VkCommandBuffer`, the buffers are allocated out of a `VkCommandPool` associated with a queue family, in order to do some simple drawing we need to do the following: - being a pass - bind the pipeline - draw 3 vertices - end the pass Since the image depends on which specific image the swap chain is going to give us, a command buffer for each possible image will have to be recorded and the right one will be selected at draw time. Recording every frame is also an option but it would be less performant. - Application main loop - acquire image via `vkAcquireNextImageKHR` - `vkAcquireNextImageKHR` to acquire an image - select appropriate command buffer for the image - execute the command buffer with `vkQueueSubmit` - return the image to the swapchain for presentation with `vkQueuePresentKHR`