Vulkan Profiles
Vulkan Profiles is a mechanism that allows developers to target a specific set of features, extensions, and limits that are guaranteed to be supported by a range of Vulkan implementations. This is particularly useful for cross-platform development where you want to ensure your application works consistently across different devices.
For detailed information, refer to the Vulkan Profiles API Library documentation on LunarG’s website.
What are Vulkan Profiles?
A Vulkan Profile is a well-defined set of capabilities, (features, extensions, formats, queue families, etc.) that can be used as a baseline for application development. Profiles are defined in JSON format and can be used to:
-
Simplify development by providing a known set of capabilities
-
Ensure compatibility across a range of devices
-
Reduce the need for complex capability checking and fallback code
-
Provide a clear target for both developers and hardware vendors
-
Automatically enable required features and extensions without manual configuration
The Khronos Group maintains a set of official profiles, and vendors can also define their own profiles for their specific hardware. Additionally, Vulkan application developers can create profiles to specify engine code paths, like Unreal Engine does. Or libraries such as Zink can specify their Vulkan requirements for OpenGL to run, enabling hardware vendors to prioritize their driver development to support specific code paths on engines or libraries.
History and Purpose
Vulkan Profiles were introduced to address the challenge of fragmentation in the Vulkan ecosystem. With many different devices supporting various combinations of features and extensions, developers faced difficulties in:
-
Determining which features to target for maximum device compatibility
-
Managing fallback paths for devices with limited capabilities
-
Communicating requirements clearly to hardware vendors
Profiles solve these problems by providing a convention to define and reference sets of Vulkan capabilities. They serve as a contract between application developers and hardware vendors, ensuring that devices claiming support for a profile will provide all the capabilities defined in that profile.
Relationship with Vulkan Versions
Vulkan Profiles are complementary to Vulkan versions. While Vulkan versions (1.0, 1.1, 1.2, etc.) define the core API functionality, profiles define specific subsets of features, extensions, and limits that may span across different Vulkan versions.
For example:
-
The Android Baseline 2022 profile requires Vulkan 1.1 core functionality
-
The LunarG Desktop Baseline 2022 profile for desktop platforms requires Vulkan 1.1 with specific extensions
-
Future profiles may target newer Vulkan versions as they become more widely supported
This approach allows developers to target specific capability sets without being tied to a particular Vulkan version, providing more flexibility in application development.
Maintained Profiles
The Khronos Group maintains several profiles, which are defined in the link:https://github.com/KhronosGroup/Vulkan-Profiles/tree/main/profiles [Vulkan-Profiles repository]. The only Khronos group maintained profiles are the Khronos Roadmap profiles. The others are maintained by Google and LunarG:
-
LunarG Desktop Baseline 2022 - A baseline profile for desktop platforms (JSON Definitions)
-
Android Baseline 2022 - A baseline profile specifically for Android devices (Documentation, JSON Definition)
-
Roadmap 2024 - A forward-looking profile that hardware vendors are encouraged to support in future implementations (Documentation, JSON Definition, roadmap)
These profiles are versioned by year to allow for evolution over time while maintaining backward compatibility. You can find sample code demonstrating the use of these profiles in the Vulkan-Samples repository.
LunarG Desktop Baseline 2022 Profile Details
The LunarG Desktop Baseline 2022 profile (VP_LUNARG_DESKTOP_BASELINE_2022
) is designed for desktop platforms. It’s described as "A profile generated by the intersection of a collection of GPUInfo.org device reports to support a large number of actual systems in the Vulkan ecosystem. This profile is meant to be a usage example for Vulkan application developers."
The real purpose of the LunarG Desktop Baseline profiles is to provide examples to Vulkan application developers to create profiles for their applications. It’s important to note that these profiles have some limitations - for example, Windows ARM / Qualcomm GPUs are not supported because these GPUs were not released or just released when the profiles were generated.
If LunarG were to create a Desktop Baseline 2025 in the future, it would likely include Windows ARM / Qualcomm GPUs, which would make the Desktop Baseline 2025 both a subset and superset (likely Vulkan 1.3) of the Desktop Baseline 2024.
The profile includes:
-
Core Vulkan 1.1 functionality
-
Key extensions such as:
-
VK_KHR_maintenance1
,VK_KHR_maintenance2
,VK_KHR_maintenance3
-
VK_KHR_create_renderpass2
-
VK_KHR_image_format_list
-
VK_KHR_sampler_mirror_clamp_to_edge
-
-
Specific feature requirements include:
-
robustBufferAccess
-
fullDrawIndexUint32
-
imageCubeArray
-
independentBlend
-
And many more core features
-
This profile ensures that applications focusing on it will work consistently across a wide range of desktop GPUs from different vendors.
Android Baseline 2022 Profile Details
The Android Baseline 2022 profile (VP_ANDROID_BASELINE_2022
) is tailored specifically for Android devices and includes:
-
Core Vulkan 1.1 functionality
-
Android-specific extensions such as:
-
VK_KHR_android_surface
-
VK_ANDROID_external_memory_android_hardware_buffer
-
-
Common rendering extensions:
-
VK_KHR_swapchain
-
VK_KHR_maintenance1
,VK_KHR_maintenance2
,VK_KHR_maintenance3
-
VK_KHR_dedicated_allocation
-
-
Mobile-optimized limits and features
This profile is particularly valuable for Android game developers who want to ensure their applications run on a wide range of Android devices without having to implement complex device-specific code paths.
Roadmap 2022 Profile
The Roadmap 2022 profile (VP_KHR_ROADMAP_2022
) is a forward-looking profile that defines capabilities that hardware vendors are encouraged to support in future implementations. It includes:
-
More advanced features and extensions beyond the baseline profiles
-
Higher minimum limits for various resources
-
Support for newer Vulkan functionality
By targeting this profile, developers can prepare their applications for future hardware capabilities while still maintaining compatibility with current devices through fallback mechanisms.
Profile Versioning Strategy
Profiles may use a year-based versioning scheme (e.g., 2022, 2023) to indicate when they were defined. This approach:
-
Provides clear temporal context for each profile
-
Allows for the creation of new profiles that reflect evolving hardware capabilities
-
Maintains backward compatibility, as older profiles are only updated to fix shortcomings or issues.
When a new yearly profile is released, it typically includes all the capabilities of the previous year’s profile plus additional features and possibly higher limits, reflecting the advancement of hardware capabilities.
Using Vulkan Profiles
There are two main ways to use Vulkan Profiles to initialize a Vulkan application:
Automatic Feature Enabling
One of the key benefits of using the Vulkan Profiles library is that it automatically handles the enabling of all required features, extensions, and properties defined in a profile. This eliminates the need to manually:
-
Track and enable each required extension
-
Set up feature structures for each feature you need
-
Configure property structures for specific requirements
When you call profile.ConfigureDeviceCreation()
, the library automatically:
-
Populates the device creation info with all necessary extensions
-
Sets up the feature chain with all required features enabled
-
Configures any required properties
This significantly simplifies device initialization and reduces the chance of errors from forgetting to enable specific features or extensions.
1. Using the Vulkan Profiles header
The simplest way to use Vulkan Profiles is through the Vulkan Profiles header (vulkan_profiles.hpp
), which is available in the Vulkan SDK. This header provides a C++ API that simplifies working with profiles. The header is documented in the Vulkan-Profiles library documentation:
#include <vulkan/vulkan.hpp>
#include <vulkan/vulkan_profiles.hpp>
// Create a profile instance for the Android baseline profile
vkp::AndroidBaseline2022Profile profile;
// Check if the profile is supported on this device
VkBool32 supported = VK_FALSE;
profile.CheckSupport(physicalDevice, &supported);
if (supported) {
// The device supports the Android baseline profile
// Use the profile to create a device
VkDeviceCreateInfo deviceCreateInfo = {};
profile.ConfigureDeviceCreation(physicalDevice, deviceCreateInfo);
// Create the device with the profile-configured create info
VkDevice device;
vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
}
2. Using the Vulkan Profiles, JSON files directly
For more advanced use cases, you can work with the JSON profile definitions directly. You can find example code that loads and uses JSON profiles in the Vulkan-Profiles:
// Load a profile from a JSON file
VkpProfilesFileLoader loader;
loader.LoadFromFile("android_baseline_2022.json");
// Get the profile
VkpProfile profile = loader.GetProfile("VP_ANDROID_BASELINE_2022");
// Use the profile to check support and create a device
// (similar to the header-based approach)
Understanding Profile JSON Structure
Vulkan Profiles are defined in JSON format with a specific structure. Understanding this structure is important for developers who want to create custom profiles or modify existing ones. Here’s a simplified example of a profile JSON structure:
{
"file_format_version": "1.0.0",
"profiles": {
"VP_EXAMPLE_PROFILE": {
"version": 1,
"api_version": "1.1.0",
"label": "Example Profile",
"description": "A simple example profile",
"capabilities": [
{
"extensions": {
"VK_KHR_swapchain": 1,
"VK_KHR_maintenance1": 1
},
"features": {
"VkPhysicalDeviceFeatures": {
"robustBufferAccess": true,
"fullDrawIndexUint32": true
}
},
"properties": {
"VkPhysicalDeviceProperties": {
"limits": {
"maxImageDimension2D": 4096,
"maxFramebufferWidth": 4096
}
}
},
"formats": {
"VK_FORMAT_R8G8B8A8_UNORM": {
"VkFormatProperties": {
"linearTilingFeatures": [
"VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT"
],
"optimalTilingFeatures": [
"VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT",
"VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT"
]
}
}
}
}
]
}
}
}
The key parts of a profile definition include:
-
Profile Metadata: Name, version, API version, label, and description
-
Capabilities: The core of the profile, defining what the profile supports
-
Extensions: Required extensions and their minimum versions
-
Features: Required features that must be supported
-
Properties: Required properties and limits
-
Formats: Required format support with specific capabilities
Types of Vulkan Profiles
Vulkan Profiles can be applied for a multitude of use cases, including:
-
Roadmap profiles: To express guidance on the future direction of Vulkan devices.
-
Platform profiles: To express the Vulkan support available on different platforms.
-
Device profiles: To express the Vulkan support of a single Vulkan driver on a Vulkan device.
-
Architecture profiles: To express the Vulkan support of a class of GPUs.
-
Engine profiles: To express some rendering code paths requirements of an engine.
-
Drivers bugs profiles: To express capabilities that can’t be used by an application.
These different types of profiles allow developers to target specific hardware configurations, platforms, or use cases, ensuring compatibility and optimal performance across a wide range of scenarios.
Creating Custom Profiles
Developers can create custom profiles to target specific hardware configurations or to define a baseline for their own applications. To create a custom profile:
There are two main use cases that define the starting point:
-
Creating a "Platform" profile - a profile that represents all the devices you want your Vulkan application to run on. Here, the starting point would be to use data from https://vulkan.gpuinfo.org/ when merging device capabilities.
-
Creating an "Engine" profile - a profile that lists all the requirements for your Vulkan application to run. In this case, modifying an existing profile is often the best approach.
Both approaches work together to ensure a Vulkan application can ship reliably.
To create a custom profile:
-
Start with an appropriate existing profile as a template (see profiles)
-
Modify the capabilities to match your requirements
-
Save the profile as a JSON file
-
Use the profile in your application using either the header-based or JSON-based approach
You can find examples of custom profiles in the Vulkan-Samples profiles examples.
Custom profiles are particularly useful for:
-
Internal development teams working on multiple applications
-
Defining minimum requirements for specific application categories
-
Creating hardware-specific optimized profiles
Example of creating and using a custom profile:
// Define a custom profile (typically done offline and saved to a JSON file)
std::string customProfileJson = R"(
{
"file_format_version": "1.0.0",
"profiles": {
"VP_CUSTOM_GAME_PROFILE": {
"version": 1,
"api_version": "1.1.0",
"label": "Custom Game Profile",
"description": "Profile for our game engine",
"capabilities": [
// ... custom capabilities ...
]
}
}
}
)";
// Load the custom profile
VkpProfilesFileLoader loader;
loader.LoadFromString(customProfileJson);
// Use the custom profile
VkpProfile profile = loader.GetProfile("VP_CUSTOM_GAME_PROFILE");
// ... use the profile as before ...
Android Baseline Profile
The Android Baseline Profile is particularly useful for Android developers as it provides a guaranteed set of features that are available on a wide range of Android devices. This profile is documented in the Vulkan Profiles API Library documentation and the JSON definition. This profile includes:
-
Core Vulkan 1.1 functionality
-
Essential extensions for Android development
-
Minimum guaranteed limits and features
By targeting the Android Baseline Profile, developers can
-
Reduce the need for device-specific code paths
-
Ensure consistent behavior across different Android devices
-
Simplify testing and validation
Example: Targeting Android Baseline Profile
#include <vulkan/vulkan.hpp>
#include <vulkan/vulkan_profiles.hpp>
void SetupVulkanWithAndroidProfile() {
// Create a Vulkan instance
vk::InstanceCreateInfo instanceCreateInfo;
vk::Instance instance = vk::createInstance(instanceCreateInfo);
// Get a physical device
vk::PhysicalDevice physicalDevice = instance.enumeratePhysicalDevices().front();
// Create a profile instance for the Android baseline profile
vkp::AndroidBaseline2022Profile profile;
// Check if the profile is supported
VkBool32 supported = VK_FALSE;
profile.CheckSupport(physicalDevice, &supported);
if (supported) {
// Configure device creation with the profile
vk::DeviceCreateInfo deviceCreateInfo;
profile.ConfigureDeviceCreation(physicalDevice, deviceCreateInfo);
// Create the device
vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
// Now you can use the device with the guaranteed set of features
// defined in the Android Baseline Profile
} else {
// Handle the case where the profile is not supported
// This might involve falling back to a simpler rendering approach
// or showing an error message
}
}
Integration with Existing Applications
Integrating Vulkan Profiles into an existing Vulkan application involves several steps, which are described in the Vulkan-Profiles library documentation:
-
Identify Target Profiles: Determine which profiles best match your application’s requirements
-
Add Profile Support: Incorporate the Vulkan Profiles header or JSON handling
-
Modify Device Creation: Update your device creation code to use profiles
-
Add Fallback Paths: Implement fallback strategies for devices that don’t support your target profile
For examples of integrating profiles with existing applications, see the Vulkan-Samples profiles examples and the Vulkan-Profiles test directory.
Here’s an example of integrating profiles into an existing application:
// Original device creation code
void CreateDeviceOriginal(VkPhysicalDevice physicalDevice) {
// Query for features, extensions, etc.
VkPhysicalDeviceFeatures features;
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
// Set up device creation info manually
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pEnabledFeatures = &features;
// ... set up extensions, queues, etc. ...
// Create the device
VkDevice device;
vkCreateDevice(physicalDevice, &createInfo, nullptr, &device);
}
// Updated device creation code using profiles
void CreateDeviceWithProfiles(VkPhysicalDevice physicalDevice) {
// Try to use the LunarG Desktop Baseline 2022 profile
vkp::LunargDesktopBaseline2022Profile profile;
VkBool32 supported = VK_FALSE;
profile.CheckSupport(physicalDevice, &supported);
if (supported) {
// Profile is supported, use it to configure device creation
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
profile.ConfigureDeviceCreation(physicalDevice, createInfo);
// Create the device with profile-configured settings
VkDevice device;
vkCreateDevice(physicalDevice, &createInfo, nullptr, &device);
} else {
// Fall back to original method if profile is not supported
CreateDeviceOriginal(physicalDevice);
}
}
Performance Considerations
Using Vulkan Profiles has minimal runtime performance impact, but there are some considerations to keep in mind:
-
Initialization Overhead: Loading and parsing profile JSON files adds some initialization time
-
Memory Usage: The profile data structures consume a small amount of memory
-
Feature Enabling: Enabling features you don’t need might have a slight performance impact on some implementations
To optimize performance when using profiles:
-
Use the header-based approach for better compile-time optimization
-
Create custom profiles that only include the features you actually need
-
Consider using different profiles for different hardware tiers
Troubleshooting and Common Issues
When working with Vulkan Profiles, developers might encounter several common issues. The Vulkan-Profiles library documentation provides guidance on troubleshooting, and the Vulkan Validation Layers documentation can help identify issues with profile usage:
Profile Isn’t Supported
If CheckSupport()
returns VK_FALSE
, it means the device doesn’t support all the requirements of the profile. To troubleshoot:
-
Use the profile’s
GetProfileCapabilitiesReport()
function to get detailed information about which specific requirements are not met -
Consider using a less demanding profile
-
Implement a fallback path for devices that don’t support your target profile
Example:
VkBool32 supported = VK_FALSE;
profile.CheckSupport(physicalDevice, &supported);
if (!supported) {
// Get detailed report on what's not supported
VkpProfileCapabilitiesReport report;
profile.GetProfileCapabilitiesReport(physicalDevice, report);
// Log the unsupported capabilities
for (const auto& unsupported : report.unsupportedCapabilities) {
LogWarning("Unsupported: " + unsupported);
}
// Fall back to a different profile or custom configuration
}
Version Compatibility Issues
When using profiles across different Vulkan SDK versions, you might encounter compatibility issues. To avoid these:
-
Always use the profile definitions from the same SDK version as your Vulkan headers
-
Be aware that profile definitions might evolve between SDK releases
-
Consider bundling the profile JSON files with your application to ensure consistency
Integration with Validation Layers
Vulkan Profiles work well with validation layers, but there are some considerations:
-
Enable the
VK_LAYER_KHRONOS_validation
layer during development -
Be aware that some validation warnings might be triggered for profile-enabled features that you’re not explicitly using
-
Use debug callbacks to filter validation messages if necessary
Benefits of Using Vulkan Profiles
Using Vulkan Profiles offers several advantages:
-
Simplified Development
-
Reduces the complexity of checking for individual features and extensions
-
Automatically enables all required features and extensions without manual configuration
-
-
Better Compatibility
-
Ensures your application works consistently across different devices
-
-
Future-Proofing
-
Profiles evolve in a controlled manner, making it easier to adapt to new hardware
-
-
Clear Communication
-
Provides a common language for developers and hardware vendors to discuss capabilities
-
-
Reduced Testing Burden
-
Fewer device-specific code paths means less testing required
-
-
Standardized Capabilities
-
Provides a well-defined baseline that hardware vendors can target
-
-
Easier Porting
-
Simplifies the process of porting applications between different platforms
-
-
Reduced Boilerplate Code
-
Eliminates the need to write extensive feature and extension enabling code
-
Conclusion
Vulkan Profiles provide a powerful mechanism for targeting a consistent set of Vulkan capabilities across different devices. By using profiles, particularly the Android Baseline Profile for mobile development, developers can simplify their code, ensure better compatibility, and reduce the need for device-specific workarounds.
The profile system continues to evolve, with new profiles being defined to address emerging hardware capabilities and developer needs. By understanding how to effectively use profiles, create custom profiles, and integrate them into your applications, you can significantly streamline your Vulkan development process.
For more information, refer to these resources:
-
-
Contains profile definitions, library code, and tools
-
-
Vulkan-Samples profiles examples
-
Sample code demonstrating profile usage
-
-
-
LunarG’s Cristophe Ricco exhaustive documentation for Vulkan Profiles.
-