Vulkan Cookbook

Book description

Work through recipes to unlock the full potential of the next generation graphics API - Vulkan

About This Book

  • This book explores a wide range of modern graphics programming techniques and GPU compute methods to make the best use of the Vulkan API
  • Learn techniques that can be applied to a wide range of platforms desktop, smartphones, and embedded devices
  • Get an idea on the graphics engine with multi-platform support and learn exciting imaging processing and post-processing techniques

Who This Book Is For

This book is ideal for developers who know C/C++ languages, have some basic familiarity with graphics programming, and now want to take advantage of the new Vulkan API in the process of building next generation computer graphics. Some basic familiarity of Vulkan would be useful to follow the recipes. OpenGL developers who want to take advantage of the Vulkan API will also find this book useful.

What You Will Learn

  • Work with Swapchain to present images on screen
  • Create, submit, and synchronize operations processed by the hardware
  • Create buffers and images, manage their memory, and upload data to them from CPU
  • Explore descriptor sets and set up an interface between application and shaders
  • Organize drawing operations into a set of render passes and subpasses
  • Prepare graphics pipelines to draw 3D scenes and compute pipelines to perform mathematical calculations
  • Implement geometry projection and tessellation, texturing, lighting, and post-processing techniques
  • Write shaders in GLSL and convert them into SPIR-V assemblies
  • Find out about and implement a collection of popular, advanced rendering techniques found in games and benchmarks

In Detail

Vulkan is the next generation graphics API released by the Khronos group. It is expected to be the successor to OpenGL and OpenGL ES, which it shares some similarities with such as its cross-platform capabilities, programmed pipeline stages, or nomenclature. Vulkan is a low-level API that gives developers much more control over the hardware, but also adds new responsibilities such as explicit memory and resources management. With it, though, Vulkan is expected to be much faster.

This book is your guide to understanding Vulkan through a series of recipes. We start off by teaching you how to create instances in Vulkan and choose the device on which operations will be performed. You will then explore more complex topics such as command buffers, resources and memory management, pipelines, GLSL shaders, render passes, and more. Gradually, the book moves on to teach you advanced rendering techniques, how to draw 3D scenes, and how to improve the performance of your applications.

By the end of the book, you will be familiar with the latest advanced techniques implemented with the Vulkan API, which can be used on a wide range of platforms.

Style and approach

This recipe-based guide will empower you to implement modern graphic programming techniques and help gain a solid understanding of the new Vulkan API.

Publisher resources

Download Example Code

Table of contents

  1. Preface
    1. What this book covers
    2. What you need for this book
    3. Who this book is for
    4. Sections
      1. Getting ready
      2. How to do it…
      3. How it works—
      4. There's more—
      5. See also
    5. Conventions
    6. Reader feedback
    7. Customer support
      1. Downloading the example code
      2. Downloading the color images of this book
      3. Errata
      4. Piracy
      5. Questions
  2. Instance and Devices
    1. Introduction
    2. Downloading Vulkan's SDK
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Enabling validation layers
      1. How to do it...
      2. How it works...
      3. See also
    4. Connecting with a Vulkan Loader library
      1. How to do it...
      2. How it works...
      3. See also
    5. Preparing for loading Vulkan API functions
      1. How to do it...
      2. How it works...
      3. See also
    6. Loading functions exported from a Vulkan Loader library
      1. How to do it...
      2. How it works...
      3. See also
    7. Loading global-level functions
      1. How to do it...
      2. How it works...
      3. See also
    8. Checking available Instance extensions
      1. How to do it...
      2. How it works...
      3. See also
    9. Creating a Vulkan Instance
      1. How to do it...
      2. How it works...
      3. See also
    10. Loading instance-level functions
      1. How to do it...
      2. How it works...
      3. See also
    11. Enumerating available physical devices
      1. How to do it...
      2. How it works...
      3. See also
    12. Checking available device extensions
      1. How to do it...
      2. How it works...
      3. See also
    13. Getting features and properties of a physical device
      1. How to do it...
      2. How it works...
      3. See also
    14. Checking available queue families and their properties
      1. How to do it...
      2. How it works...
      3. See also
    15. Selecting the index of a queue family with the desired capabilities
      1. How to do it...
      2. How it works...
      3. See also
    16. Creating a logical device
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    17. Loading device-level functions
      1. How to do it...
      2. How it works...
      3. See also
    18. Getting a device queue
      1. How to do it...
      2. How it works...
      3. See also
    19. Creating a logical device with geometry shaders, graphics, and compute queues
      1. How to do it...
      2. How it works...
      3. See also
    20. Destroying a logical device
      1. How to do it...
      2. How it works...
      3. See also
    21. Destroying a Vulkan Instance
      1. How to do it...
      2. How it works...
      3. See also
    22. Releasing a Vulkan Loader library
      1. How to do it...
      2. How it works...
      3. See also
  3. Image Presentation
    1. Introduction
    2. Creating a Vulkan Instance with WSI extensions enabled
      1. How to do it...
      2. How it works...
      3. See also
    3. Creating a presentation surface
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Selecting a queue family that supports presentation to a given surface
      1. How to do it...
      2. How it works...
      3. See also
    5. Creating a logical device with WSI extensions enabled
      1. How to do it...
      2. How it works...
      3. See also
    6. Selecting a desired presentation mode
      1. How to do it...
      2. How it works...
      3. See also
    7. Getting the capabilities of a presentation surface
      1. How to do it...
      2. How it works...
      3. See also
    8. Selecting a number of swapchain images
      1. How to do it...
      2. How it works...
      3. See also
    9. Choosing a size of swapchain images
      1. How to do it...
      2. How it works...
      3. See also
    10. Selecting desired usage scenarios of swapchain images
      1. How to do it...
      2. How it works...
      3. See also
    11. Selecting a transformation of swapchain images
      1. How to do it...
      2. How it works...
      3. See also
    12. Selecting a format of swapchain images
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    13. Creating a swapchain
      1. How to do it...
      2. How it works...
      3. See also
    14. Getting handles of swapchain images
      1. How to do it...
      2. How it works...
      3. See also
    15. Creating a swapchain with R8G8B8A8 format and a mailbox present mode
      1. How to do it...
      2. How it works...
      3. See also
    16. Acquiring a swapchain image
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    17. Presenting an image
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    18. Destroying a swapchain
      1. How to do it...
      2. How it works...
      3. See also
    19. Destroying a presentation surface
      1. How to do it...
      2. How it works...
      3. See also
  4. Command Buffers and Synchronization
    1. Introduction
    2. Creating a command pool
      1. How to do it...
      2. How it works...
      3. See also
    3. Allocating command buffers
      1. How to do it...
      2. How it works...
      3. See also
    4. Beginning a command buffer recording operation
      1. How to do it...
      2. How it works...
      3. See also
    5. Ending a command buffer recording operation
      1. How to do it...
      2. How it works...
      3. See also
    6. Resetting a command buffer
      1. How to do it...
      2. How it works...
      3. See also
    7. Resetting a command pool
      1. How to do it...
      2. How it works...
      3. See also
    8. Creating a semaphore
      1. How to do it...
      2. How it works...
      3. See also
    9. Creating a fence
      1. How to do it...
      2. How it works...
      3. See also
    10. Waiting for fences
      1. How to do it...
      2. How it works...
      3. See also
    11. Resetting fences
      1. How to do it...
      2. How it works...
      3. See also
    12. Submitting command buffers to a queue
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    13. Synchronizing two command buffers
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    14. Checking if processing of a submitted command buffer has finished
      1. How to do it...
      2. How it works...
      3. See also
    15. Waiting until all commands submitted to a queue are finished
      1. How to do it...
      2. How it works...
      3. See also
    16. Waiting for all submitted commands to be finished
      1. How to do it...
      2. How it works...
      3. See also
    17. Destroying a fence
      1. How to do it...
      2. How it works...
      3. See also
    18. Destroying a semaphore
      1. How to do it...
      2. How it works...
      3. See also
    19. Freeing command buffers
      1. How to do it...
      2. How it works...
      3. See also
    20. Destroying a command pool
      1. How to do it...
      2. How it works...
      3. See also
  5. Resources and Memory
    1. Introduction
    2. Creating a buffer
      1. How to do it...
      2. How it works...
      3. See also
    3. Allocating and binding a memory object for a buffer
      1. How to do it...
      2. How it works...
      3. There's more...
      4. See also
    4. Setting a buffer memory barrier
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. There's more...
      5. See also
    5. Creating a buffer view
      1. How to do it...
      2. How it works...
      3. See also
    6. Creating an image
      1. How to do it...
      2. How it works...
      3. See also
    7. Allocating and binding a memory object to an image
      1. How to do it...
      2. How it works...
      3. There's more...
      4. See also
    8. Setting an image memory barrier
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    9. Creating an image view
      1. How to do it...
      2. How it works...
      3. See also
    10. Creating a 2D image and view
      1. How to do it...
      2. How it works...
      3. See also
    11. Creating a layered 2D image with a CUBEMAP view
      1. How to do it...
      2. How it works...
      3. See also
    12. Mapping, updating and unmapping host-visible memory
      1. How to do it...
      2. How it works...
      3. See also
    13. Copying data between buffers
      1. How to do it...
      2. How it works...
      3. See also
    14. Copying data from a buffer to an image
      1. How to do it...
      2. How it works...
      3. See also
    15. Copying data from an image to a buffer
      1. How to do it...
      2. How it works...
      3. See also
    16. Using a staging buffer to update a buffer with a device-local memory bound
      1. How to do it...
      2. How it works...
      3. See also
    17. Using a staging buffer to update an image with a device-local memory bound
      1. How to do it...
      2. How it works...
      3. See also
    18. Destroying an image view
      1. How to do it...
      2. How it works...
      3. See also
    19. Destroying an image
      1. How to do it...
      2. How it works...
      3. See also
    20. Destroying a buffer view
      1. How to do it...
      2. How it works...
      3. See also
    21. Freeing a memory object
      1. How to do it...
      2. How it works...
      3. See also
    22. Destroying a buffer
      1. How to do it...
      2. How it works...
      3. See also
  6. Descriptor Sets
    1. Introduction
    2. Creating a sampler
      1. How to do it...
      2. How it works...
      3. See also
    3. Creating a sampled image
      1. How to do it...
      2. How it works...
      3. See also
    4. Creating a combined image sampler
      1. How to do it...
      2. How it works...
      3. See also
    5. Creating a storage image
      1. How to do it...
      2. How it works...
      3. See also
    6. Creating a uniform texel buffer
      1. How to do it...
      2. How it works...
      3. See also
    7. Creating a storage texel buffer
      1. How to do it...
      2. How it works...
      3. See also
    8. Creating a uniform buffer
      1. How to do it...
      2. How it works...
      3. See also
    9. Creating a storage buffer
      1. How to do it...
      2. How it works...
      3. See also
    10. Creating an input attachment
      1. How to do it...
      2. How it works...
      3. See also
    11. Creating a descriptor set layout
      1. How to do it...
      2. How it works...
      3. See also
    12. Creating a descriptor pool
      1. How to do it...
      2. How it works...
      3. See also
    13. Allocating descriptor sets
      1. How to do it...
      2. How it works...
      3. See also
    14. Updating descriptor sets
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    15. Binding descriptor sets
      1. How to do it...
      2. How it works...
      3. See also
    16. Creating descriptors with a texture and a uniform buffer
      1. How to do it...
      2. How it works...
      3. See also
    17. Freeing descriptor sets
      1. How to do it...
      2. How it works...
      3. See also
    18. Resetting a descriptor pool
      1. How to do it...
      2. How it works...
      3. See also
    19. Destroying a descriptor pool
      1. How to do it...
      2. How it works...
      3. See also
    20. Destroying a descriptor set layout
      1. How to do it...
      2. How it works...
      3. See also
    21. Destroying a sampler
      1. How to do it...
      2. How it works...
      3. See also
  7. Render Passes and Framebuffers
    1. Introduction
    2. Specifying attachments descriptions
      1. How to do it...
      2. How it works...
      3. See also
    3. Specifying subpass descriptions
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Specifying dependencies between subpasses
      1. How to do it...
      2. How it works...
      3. See also
    5. Creating a render pass
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Creating a framebuffer
      1. How to do it...
      2. How it works...
      3. See also
    7. Preparing a render pass for geometry rendering and postprocess subpasses
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Preparing a render pass and a framebuffer with color and depth attachments
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    9. Beginning a render pass
      1. How to do it...
      2. How it works...
      3. See also
    10. Progressing to the next subpass
      1. How to do it...
      2. How it works...
      3. See also
    11. Ending a render pass
      1. How to do it...
      2. How it works...
      3. See also
    12. Destroying a framebuffer
      1. How to do it...
      2. How it works...
      3. See also
    13. Destroying a render pass
      1. How to do it...
      2. How it works...
      3. See also
  8. Shaders
    1. Introduction
    2. Converting GLSL shaders to SPIR-V assemblies
      1. How to do it...
      2. How it works...
      3. See also
    3. Writing vertex shaders
      1. How to do it...
      2. How it works...
      3. See also
    4. Writing tessellation control shaders
      1. How to do it...
      2. How it works...
      3. See also
    5. Writing tessellation evaluation shaders
      1. How to do it...
      2. How it works...
      3. See also
    6. Writing geometry shaders
      1. How to do it...
      2. How it works...
      3. See also
    7. Writing fragment shaders
      1. How to do it...
      2. How it works...
      3. See also
    8. Writing compute shaders
      1. How to do it...
      2. How it works...
      3. See also
    9. Writing a vertex shader that multiplies vertex position by a projection matrix
      1. How to do it...
      2. How it works...
      3. See also
    10. Using push constants in shaders
      1. How to do it...
      2. How it works...
      3. See also
    11. Writing texturing vertex and fragment shaders
      1. How to do it...
      2. How it works...
      3. See also
    12. Displaying polygon normals with a geometry shader
      1. How to do it...
      2. How it works...
      3. See also
  9. Graphics and Compute Pipelines
    1. Introduction
    2. Creating a shader module
      1. How to do it...
      2. How it works...
      3. See also
    3. Specifying pipeline shader stages
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Specifying a pipeline vertex binding description, attribute description, and input state
      1. How to do it...
      2. How it works...
      3. See also
    5. Specifying a pipeline input assembly state
      1. How to do it...
      2. How it works...
      3. See also
    6. Specifying a pipeline tessellation state
      1. How to do it...
      2. How it works...
      3. See also
    7. Specifying a pipeline viewport and scissor test state
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Specifying a pipeline rasterization state
      1. How to do it...
      2. How it works...
      3. See also
    9. Specifying a pipeline multisample state
      1. How to do it...
      2. How it works...
      3. See also
    10. Specifying a pipeline depth and stencil state
      1. How to do it...
      2. How it works...
      3. See also
    11. Specifying a pipeline blend state
      1. How to do it...
      2. How it works...
      3. See also
    12. Specifying pipeline dynamic states
      1. How to do it...
      2. How it works...
      3. See also
    13. Creating a pipeline layout
      1. How to do it...
      2. How it works...
      3. See also
    14. Specifying graphics pipeline creation parameters
      1. How to do it...
      2. How it works...
      3. See also
    15. Creating a pipeline cache object
      1. How to do it...
      2. How it works...
      3. See also
    16. Retrieving data from a pipeline cache
      1. How to do it...
      2. How it works...
      3. See also
    17. Merging multiple pipeline cache objects
      1. How to do it...
      2. How it works...
      3. See also
    18. Creating a graphics pipeline
      1. How to do it...
      2. How it works...
      3. See also
    19. Creating a compute pipeline
      1. How to do it...
      2. How it works...
      3. See also
    20. Binding a pipeline object
      1. How to do it...
      2. How it works...
      3. See also
    21. Creating a pipeline layout with a combined image sampler, a buffer, and push constant ranges
      1. How to do it...
      2. How it works...
      3. See also
    22. Creating a graphics pipeline with vertex and fragment shaders, depth test enabled, and with dynamic viewport and scissor tests
      1. How to do it...
      2. How it works...
      3. See also
    23. Creating multiple graphics pipelines on multiple threads
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    24. Destroying a pipeline
      1. How to do it...
      2. How it works...
      3. See also
    25. Destroying a pipeline cache
      1. How to do it...
      2. How it works...
      3. See also
    26. Destroying a pipeline layout
      1. How to do it...
      2. How it works...
      3. See also
    27. Destroying a shader module
      1. How to do it...
      2. How it works...
      3. See also
  10. Command Recording and Drawing
    1. Introduction
    2. Clearing a color image
      1. How to do it...
      2. How it works...
      3. See also
    3. Clearing a depth-stencil image
      1. How to do it...
      2. How it works...
      3. See also
    4. Clearing render pass attachments
      1. How to do it...
      2. How it works...
      3. See also
    5. Binding vertex buffers
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Binding an index buffer
      1. How to do it...
      2. How it works...
      3. See also
    7. Providing data to shaders through push constants
      1. How to do it...
      2. How it works...
      3. See also
    8. Setting viewport states dynamically
      1. How to do it...
      2. How it works...
      3. See also
    9. Setting scissor states dynamically
      1. How to do it...
      2. How it works...
      3. See also
    10. Setting line width states dynamically
      1. How to do it...
      2. How it works...
      3. See also
    11. Setting depth bias states dynamically
      1. How to do it...
      2. How it works...
      3. See also
    12. Setting blend constants states dynamically
      1. How to do it...
      2. How it works...
      3. See also
    13. Drawing a geometry
      1. How to do it...
      2. How it works...
      3. See also
    14. Drawing an indexed geometry
      1. How to do it...
      2. How it works...
      3. See also
    15. Dispatching compute work
      1. How to do it...
      2. How it works...
      3. See also
    16. Executing a secondary command buffer inside a primary command buffer
      1. How to do it...
      2. How it works...
      3. See also
    17. Recording a command buffer that draws a geometry with dynamic viewport and scissor states
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    18. Recording command buffers on multiple threads
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    19. Preparing a single frame of animation
      1. How to do it...
      2. How it works...
      3. See also
    20. Increasing the performance through increasing the number of separately rendered frames
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
  11. Helper Recipes
    1. Introduction
    2. Preparing a translation matrix
      1. How to do it...
      2. How it works...
      3. See also
    3. Preparing a rotation matrix
      1. How to do it...
      2. How it works...
      3. See also
    4. Preparing a scaling matrix
      1. How to do it...
      2. How it works...
      3. See also
    5. Preparing a perspective projection matrix
      1. How to do it...
      2. How it works...
      3. See also
    6. Preparing an orthographic projection matrix
      1. How to do it...
      2. How it works...
      3. See also
    7. Loading texture data from a file
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    8. Loading a 3D model from an OBJ file
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
  12. Lighting
    1. Introduction
    2. Rendering a geometry with a vertex diffuse lighting
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Rendering a geometry with a fragment specular lighting
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    4. Rendering a normal mapped geometry
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    5. Drawing a reflective and refractive geometry using cubemaps
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Adding shadows to the scene
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
  13. Advanced Rendering Techniques
    1. Introduction
    2. Drawing a skybox
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    3. Drawing billboards using geometry shaders
      1. How to do it...
      2. How it works...
      3. See also
    4. Drawing particles using compute and graphics pipelines
      1. How to do it...
      2. How it works...
      3. See also
    5. Rendering a tessellated terrain
      1. Getting ready
      2. How to do it...
      3. How it works...
      4. See also
    6. Rendering a full-screen quad for post-processing
      1. How to do it...
      2. How it works...
      3. See also
    7. Using input attachments for a color correction post-process effect
      1. How to do it...
      2. How it works...
      3. See also

Product information

  • Title: Vulkan Cookbook
  • Author(s): Pawel Lapinski
  • Release date: April 2017
  • Publisher(s): Packt Publishing
  • ISBN: 9781786468154