Vulkan Cookbook
eBook - ePub

Vulkan Cookbook

Pawel Lapinski

Share book
  1. 700 pages
  2. English
  3. ePUB (mobile friendly)
  4. Available on iOS & Android
eBook - ePub

Vulkan Cookbook

Pawel Lapinski

Book details
Book preview
Table of contents
Citations

About This Book

Work through recipes to unlock the full potential of the next generation graphics API—VulkanAbout 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 techniquesWho This Book Is ForThis 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 benchmarksIn DetailVulkan 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 approachThis recipe-based guide will empower you to implement modern graphic programming techniques and help gain a solid understanding of the new Vulkan API.

Frequently asked questions

How do I cancel my subscription?
Simply head over to the account section in settings and click on “Cancel Subscription” - it’s as simple as that. After you cancel, your membership will stay active for the remainder of the time you’ve paid for. Learn more here.
Can/how do I download books?
At the moment all of our mobile-responsive ePub books are available to download via the app. Most of our PDFs are also available to download and we're working on making the final remaining ones downloadable now. Learn more here.
What is the difference between the pricing plans?
Both plans give you full access to the library and all of Perlego’s features. The only differences are the price and subscription period: With the annual plan you’ll save around 30% compared to 12 months on the monthly plan.
What is Perlego?
We are an online textbook subscription service, where you can get access to an entire online library for less than the price of a single book per month. With over 1 million books across 1000+ topics, we’ve got you covered! Learn more here.
Do you support text-to-speech?
Look out for the read-aloud symbol on your next book to see if you can listen to it. The read-aloud tool reads text aloud for you, highlighting the text as it is being read. You can pause it, speed it up and slow it down. Learn more here.
Is Vulkan Cookbook an online PDF/ePUB?
Yes, you can access Vulkan Cookbook by Pawel Lapinski in PDF and/or ePUB format, as well as other popular books in Computer Science & Computer Graphics. We have over one million books available in our catalogue for you to explore.

Information

Year
2017
ISBN
9781786464705
Edition
1

Graphics and Compute Pipelines

In this chapter, we will cover the following recipes:
  • Creating a shader module
  • Specifying pipeline shader stages
  • Specifying a pipeline vertex binding description, attribute description, and input state
  • Specifying a pipeline input assembly state
  • Specifying a pipeline tessellation state
  • Specifying a pipeline viewport and scissor test state
  • Specifying a pipeline rasterization state
  • Specifying a pipeline multisample state
  • Specifying a pipeline depth and stencil state
  • Specifying a pipeline blend state
  • Specifying pipeline dynamic states
  • Creating a pipeline layout
  • Specifying graphics pipeline creation parameters
  • Creating a pipeline cache object
  • Retrieving data from a pipeline cache
  • Merging multiple pipeline cache objects
  • Creating a graphics pipeline
  • Creating a compute pipeline
  • Binding a pipeline object
  • Creating a pipeline layout with a combined image sampler, a buffer, and push constant ranges
  • Creating a graphics pipeline with vertex and fragment shaders, depth test enabled, and with dynamic viewport and scissor tests
  • Creating multiple graphics pipelines on multiple threads
  • Destroying a pipeline
  • Destroying a pipeline cache
  • Destroying a pipeline layout
  • Destroying a shader module

Introduction

Operations recorded in command buffers and submitted to queues are processed by the hardware. Processing is performed in a series of steps that form a pipeline. When we want to perform mathematical calculations, we use a compute pipeline. If we want to draw anything, we need a graphics pipeline.
Pipeline objects control the way in which geometry is drawn or computations are performed. They manage the behavior of the hardware on which our application is executed. And they are one of the biggest and most apparent differences between Vulkan and OpenGL. OpenGL used a state machine. It allowed us to change many rendering or computing parameters whenever we wanted. We could set up the state, activate a shader program, draw a geometry, then activate another shader program and draw another geometry. In Vulkan it is not possible because the whole rendering or computing state is stored in a single, monolithical object. When we want to use a different set of shaders, we need to prepare and use a separate pipeline. We can't just switch shaders.
This may be intimidating at first because many shader variations (not including the rest of the pipeline state) cause us to create multiple pipeline objects. But it serves two important goals. The first is the performance. Drivers that know the whole state in advance may optimize execution of the following operations. The second goal is the stability of the performance. Changing the state whenever we want may cause the driver to perform additional operations, such as shader recompilation, in unexpected and unpredictable moments. In Vulkan, all the required preparations, including shader compilation, are done only during the pipeline creation.
In this chapter, we will see how to set up all of the graphics or compute pipelines parameters to successfully create them. We will see how to prepare shader modules and define which shader stages are active, how to set up depth or stencil tests and how to enable blending. We will also specify what vertex attributes are used and how they are provided during drawing operations. Finally, we will see how to create multiple pipelines and how to improve the speed of their creation.

Creating a shader module

The first step in creating a pipeline object is to prepare shader modules. They represent shaders and contain their code written in a SPIR-V assembly. A single module may contain code for multiple shader stages. When we write shader programs and convert them into SPIR-V form, we need to create a shader module (or multiple modules) before we can use shaders in our application.

How to do it...

  1. Take the handle of a logical device stored in a variable of type VkDevice named logical_device.
  2. Load a binary SPIR-V assembly of a selected shader and store it in a variable of type std::vector<unsigned char> named source_code.
  3. Create a variable of type VkShaderModuleCreateInfo named shader_module_create_info. Use the following values to initialize its members:
    • VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO value for sType.
    • nullptr value for pNext
    • 0 value for flags
    • The number of elements in the source_code vector (size in bytes) for codeSize
    • A pointer to the first element of the source_code variable for pCode
  4. Create a variable of type VkShaderModule named shader_module in which the handle of a created shader module will be stored.
  1. Make the vkCreateShaderModule( logical_device, &shader_module_create_info, nullptr, &shader_module ) function call for which provide the logical_device variable, a pointer to the shader_module_create_info, a nullptr value, and a pointer to the shader_module variable.
  2. Make sure the vkCreateShaderModule() function call returned a VK_SUCCESS value which indicates that the shader module was properly created.

How it works...

Shader modules contain source code--a single SPIR-V assembly--of selected shader programs. It may represent multiple shader stages but a separate entry point must be associated with each stage. This entry point is then provided as one of the parameters when we create a pipeline object (refer to the Specifying pipeline shader stages recipe).
When we want to create a shader module, we need to load a file with the binary SPIR-V code or acquire it in any other way. Then we provide it to a variable of type VkShaderModuleCreateInfo like this:
 VkShaderModuleCreateInfo shader_module_create_info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, nullptr, 0, source_code.size(), reinterpret_cast<uint32_t const *>(source_code.data()) }; 
Next, the pointer to such a variable is provided to the vkCreateShaderModule() function, which creates a module:
 VkResult result = vkCreateShaderModule( logical_device, &shader_module_create_info, nullptr, &shader_module ); if( VK_SUCCESS != result ) { std::cout << "Could not create a shader module." << std::endl; return false; } return true; 
We just need to remember that shaders are not compiled when we create a shader module; this is done when we create a pipeline object.
Shader compilation and linkage is performed during the pipeline object creation.

See also

The following recipes in this chapter:
  • Specifying pipeline shader stages
  • Creating a graphics pipeline
  • Creating a compute pipeline
  • Destroying a shader module

Specifying pipeline shader stages

In compute pipelines, we can use only compute shaders. But graphics pipelines may contain multiple shader stages--vertex (which is obligatory), geometry, tessellation control and evaluation, and fragment. So for the pipeline to be properly created, we need to specify what programmable shader stages will be active when a given pipeline is bound to a command buffer. And we also need to provide a source code for all the enabled shaders.

Getting ready

To simplify the recipe and lower the number of parameters needed to prepare descriptions of all enabled shader stages, a custom ShaderStageParameters type is introduced. It has the following definition:
 structShaderStageParameters { VkShaderStageFlagBits ShaderStage; VkShaderModule ShaderModule; char const * EntryPointName; VkSpecializationInfo const * SpecializationInfo; }; 
In the preceding structure, ShaderStage defines a single pipeline stage for which the rest of the parameters are specified. ShaderModule is a module from which a SPIR-V source code for the given stage can be taken, associated with a function whose name is provided in the EntryPointName member. The SpecializationInfo parameter is a pointer to a variable of type VkSpecializationInfo. It allows values of the constant variables defined in the shader source code to be modified at runtime, during pipeline creation. But if we don't want to specify constant values, we can provide a nullptr value.

How to do it...

  1. Create a shader module or modules containing source code for each shader stage that will be active in a given pipeline (refer to the Creating a shader module recipe).
  2. Create a std::vector variable named shader_stage_create_infos with elements of type VkPipelineShaderStageCreateInfo.
  3. For each shader stage that should be enabled in a given pipeline, add an element to the shader_stage_create_infos vector and use the following values to initialize its members:
    • VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO value for sType
    • nullptr value for pNext
    • 0 value for flags
    • The selected shader stage for stage
    • The shader module with a source code of a given shader stage for module
    • The name of the fu...

Table of contents