226 lines
9.6 KiB
C++
226 lines
9.6 KiB
C++
/*
|
|
* Copyright 2025 Google LLC
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef skgpu_VulkanPreferredFeatures_DEFINED
|
|
#define skgpu_VulkanPreferredFeatures_DEFINED
|
|
|
|
#include "include/private/base/SkAPI.h"
|
|
#include "include/private/gpu/vk/SkiaVulkan.h"
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
namespace skgpu {
|
|
|
|
class SK_API VulkanPreferredFeatures {
|
|
public:
|
|
~VulkanPreferredFeatures();
|
|
|
|
/*
|
|
* VulkanPreferredFeatures is used by Skia to add extensions and features on top of what the app
|
|
* wants to enable. The flow of Vulkan initialization for an app that wants to use Skia would
|
|
* be:
|
|
*
|
|
* ```
|
|
* // Query the loader for instance information, decide on API version to use
|
|
*
|
|
* // Prepare for Skia-enabled extensions and features
|
|
* skgpu::VulkanPreferredFeatures skiaFeatures;
|
|
* skiaFeatures.init(apiVersion);
|
|
*
|
|
* // Decide on instance extensions to use in the app.
|
|
*
|
|
* // Allow Skia to add to the instance extension list.
|
|
* skiaFeatures.addToInstanceExtensions(...);
|
|
*
|
|
* // Create the instance, choose physical device, query available extensions, decide on
|
|
* // device features to query
|
|
*
|
|
* // Allow Skia to add to the feature query list.
|
|
* skiaFeatures.addFeaturesToQuery(...);
|
|
*
|
|
* // Query features, decide on extensions and features to enable.
|
|
*
|
|
* // Allow Skia to add to the device extension and feature list.
|
|
* skiaFeatures.addFeaturesToEnable(...);
|
|
*
|
|
* // Create the Vulkan device.
|
|
* ```
|
|
*
|
|
* Parameters:
|
|
*
|
|
* * appAPIVersion: The API version the app has specified in VkApplicationInfo::apiVersion (and
|
|
* will later provide in VulkanBackendContext::fMaxAPIVersion). The minimum supported version
|
|
* is VK_API_VERSION_1_1, maximum is VK_API_VERSION_1_4.
|
|
*/
|
|
void init(uint32_t appAPIVersion);
|
|
|
|
/*
|
|
* Before creating a Vulkan instance, call addToInstanceExtensions to give Skia a chance to add
|
|
* instance extensions it may take advantage of. Extensions are only added to appExtensions if
|
|
* caller hasn't already included them to be enabled.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* * instanceExtensions, instanceExtensionCount: The list of available instance extensions as
|
|
* queried from the loader.
|
|
* * appExtensions: The list of extensions to be enabled on the instance; more extensions may be
|
|
* added to this list by this call.
|
|
*/
|
|
void addToInstanceExtensions(const VkExtensionProperties* instanceExtensions,
|
|
size_t instanceExtensionCount,
|
|
std::vector<const char*>& appExtensions);
|
|
|
|
/*
|
|
* Before querying Vulkan device features, call addFeaturesToQuery to give Skia a chance to add
|
|
* device extension features it may take advantage of to the query. Features are only added to
|
|
* appFeatures if caller hasn't already included them in the query.
|
|
*
|
|
* Beware that the structs that get chained to appFeatures are member variables of this class,
|
|
* so this object must not leave scope until feature query and device creation is complete.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* * deviceExtensions, deviceExtensionCount: The list of available device extensions as queried
|
|
* from the physical device.
|
|
* * appFeatures: The features to be queried from the physical device; more features may be
|
|
* added to the pNext chain by this call.
|
|
*/
|
|
void addFeaturesToQuery(const VkExtensionProperties* deviceExtensions,
|
|
size_t deviceExtensionCount,
|
|
VkPhysicalDeviceFeatures2& appFeatures);
|
|
|
|
/*
|
|
* Before creating the Vulkan device, call addFeaturesToEnable to give Skia a chance to add
|
|
* device extensions and features it may take advantage of. Extensions and features are only
|
|
* added to appExtensions and appFeatures respectively if caller hasn't already included them to
|
|
* be enabled. This function may replace chained features with VkPhysicalDeviceVulkanNNFeatures
|
|
* structs instead in order to add features. Features that are already enabled by the
|
|
* application are retained in that case in the new struct.
|
|
*
|
|
* Parameters:
|
|
*
|
|
* * appExtensions: The list of extensions to be enabled on the device; more extensions may be
|
|
* added to this list by this call.
|
|
* * appFeatures: The features to be enabled on the device; more features may be
|
|
* added to the pNext chain by this call.
|
|
*/
|
|
void addFeaturesToEnable(std::vector<const char*>& appExtensions,
|
|
VkPhysicalDeviceFeatures2& appFeatures);
|
|
|
|
private:
|
|
uint32_t fAPIVersion = 0;
|
|
// Track what the application did, so warnings can be generated if the class is not
|
|
// fully/correctly used.
|
|
bool fHasAddedToInstanceExtensions = false;
|
|
bool fHasAddedFeaturesToQuery = false;
|
|
bool fHasAddedFeaturesToEnable = false;
|
|
|
|
// The list of device features Skia is interested in. If any are included in
|
|
// VkPhysicalDeviceFeatures2::pNext by the app, it is not included again by Skia. However, to
|
|
// take best advantage of the Vulkan API, the app should not intentionally include these feature
|
|
// structs only to forcefully disable the feature - this blocks Skia from leveraging it.
|
|
//
|
|
// When ambiguous, the extension name is included to determine which extension a feature struct
|
|
// has come from. This is usually needed when addFeaturesToQuery has included a feature struct
|
|
// that is present in multiple extensions (e.g. due to extension promotion). It is later used by
|
|
// addFeaturesToEnable to know which extension to enable.
|
|
|
|
// Available since Vulkan 1.2
|
|
VkPhysicalDeviceVulkan11Features fVulkan11 = {};
|
|
|
|
// Available since Vulkan 1.2
|
|
VkPhysicalDeviceVulkan12Features fVulkan12 = {};
|
|
|
|
// Available since Vulkan 1.3
|
|
VkPhysicalDeviceVulkan13Features fVulkan13 = {};
|
|
|
|
// Available since Vulkan 1.4
|
|
VkPhysicalDeviceVulkan14Features fVulkan14 = {};
|
|
|
|
// Feature of VK_EXT_rasterization_order_attachment_access or
|
|
// VK_ARM_rasterization_order_attachment_access.
|
|
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT
|
|
fRasterizationOrderAttachmentAccess = {};
|
|
const char* fRasterizationOrderAttachmentAccessExtension = nullptr;
|
|
|
|
// Feature of VK_EXT_blend_operation_advanced
|
|
VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT fBlendOperationAdvanced = {};
|
|
|
|
// Feature of VK_EXT_extended_dynamic_state
|
|
VkPhysicalDeviceExtendedDynamicStateFeaturesEXT fExtendedDynamicState = {};
|
|
|
|
// Feature of VK_EXT_extended_dynamic_state2
|
|
VkPhysicalDeviceExtendedDynamicState2FeaturesEXT fExtendedDynamicState2 = {};
|
|
|
|
// Feature of VK_EXT_vertex_input_dynamic_state
|
|
VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT fVertexInputDynamicState = {};
|
|
|
|
// Feature of VK_EXT_graphics_pipeline_library
|
|
VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT fGraphicsPipelineLibrary = {};
|
|
|
|
// Feature of VK_KHR_sampler_ycbcr_conversion or Vulkan 1.1
|
|
VkPhysicalDeviceSamplerYcbcrConversionFeatures fSamplerYcbcrConversion = {};
|
|
|
|
// Feature of VK_EXT_rgba10x6_formats
|
|
VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT fRGBA10x6Formats = {};
|
|
|
|
// Feature of VK_KHR_synchronization2 or Vulkan 1.3
|
|
VkPhysicalDeviceDynamicRenderingFeatures fSynchronization2 = {};
|
|
|
|
// Feature of VK_KHR_dynamic_rendering or Vulkan 1.3
|
|
VkPhysicalDeviceDynamicRenderingFeatures fDynamicRendering = {};
|
|
|
|
// Feature of VK_KHR_dynamic_rendering_local_read or Vulkan 1.4
|
|
VkPhysicalDeviceDynamicRenderingLocalReadFeatures fDynamicRenderingLocalRead = {};
|
|
|
|
// Feature of VK_EXT_multisampled_render_to_single_sampled
|
|
VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT
|
|
fMultisampledRenderToSingleSampled = {};
|
|
|
|
// Feature of VK_EXT_host_image_copy or Vulkan 1.4
|
|
VkPhysicalDeviceHostImageCopyFeatures fHostImageCopy = {};
|
|
|
|
// Feature of VK_EXT_pipeline_creation_cache_control or Vulkan 1.3
|
|
VkPhysicalDevicePipelineCreationCacheControlFeatures fPipelineCreationCacheControl = {};
|
|
|
|
// Feature of VK_EXT_frame_boundary
|
|
VkPhysicalDeviceFrameBoundaryFeaturesEXT fFrameBoundary = {};
|
|
|
|
// Extensions that don't have a feature:
|
|
// VK_KHR_driver_properties or Vulkan 1.2
|
|
const char* fDriverPropertiesExtension = nullptr;
|
|
// VK_KHR_create_renderpass2 or Vulkan 1.2
|
|
const char* fCreateRenderpass2Extension = nullptr;
|
|
// VK_EXT_load_store_op_none, VK_KHR_load_store_op_none or Vulkan 1.4
|
|
const char* fLoadStoreOpNoneExtension = nullptr;
|
|
// VK_EXT_conservative_rasterization
|
|
const char* fConservativeRasterizationExtension = nullptr;
|
|
#if defined(SK_BUILD_FOR_ANDROID)
|
|
// VK_ANDROID_external_memory_android_hardware_buffer
|
|
const char* fExternalMemoryAHardwareBufferExtension = nullptr;
|
|
#endif
|
|
|
|
// Extensions that the other extensions above depend on:
|
|
// Dependency of VK_EXT_graphics_pipeline_library: VK_KHR_pipeline_library
|
|
const char* fPipelineLibraryExtension = nullptr;
|
|
// Dependencies of VK_EXT_host_image_copy: VK_KHR_copy_commands2, VK_KHR_format_feature_flags2
|
|
const char* fCopyCommands2Extension = nullptr;
|
|
const char* fFormatFeatureFlags2Extension = nullptr;
|
|
// Dependency of VK_EXT_multisampled_render_to_single_sampled: VK_KHR_depth_stencil_resolve
|
|
const char* fDepthStencilResolveExtension = nullptr;
|
|
#if defined(SK_BUILD_FOR_ANDROID)
|
|
// Dependency of VK_ANDROID_external_memory_android_hardware_buffer: VK_EXT_queue_family_foreign
|
|
const char* fQueueFamilyForeignExtension = nullptr;
|
|
#endif
|
|
};
|
|
|
|
} // namespace skgpu
|
|
|
|
#endif // skgpu_VulkanPreferredFeatures_DEFINED
|