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.

    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