14#ifndef SK_GPU_TOOLS_VK_LIBRARY_NAME
16 #define SK_GPU_TOOLS_VK_LIBRARY_NAME vulkan-1.dll
17 #elif defined SK_BUILD_FOR_MAC
18 #define SK_GPU_TOOLS_VK_LIBRARY_NAME libvk_swiftshader.dylib
20 #define SK_GPU_TOOLS_VK_LIBRARY_NAME libvulkan.so
21 #define SK_GPU_TOOLS_VK_LIBRARY_NAME_BACKUP libvulkan.so.1
25#define STRINGIFY2(S) #S
26#define STRINGIFY(S) STRINGIFY2(S)
38#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
39#include <sanitizer/lsan_interface.h>
47 static void* vkLib =
nullptr;
54#ifdef SK_GPU_TOOLS_VK_LIBRARY_NAME_BACKUP
64 "vkGetInstanceProcAddr");
69 *instProc = localInstProc;
76#ifdef SK_ENABLE_VK_LAYERS
77const char* kDebugLayerNames[] = {
79 "VK_LAYER_KHRONOS_validation",
86static uint32_t remove_patch_version(uint32_t specVersion) {
87 return (specVersion >> 12) << 12;
91static int should_include_debug_layer(
const char* layerName,
94 for (uint32_t
i = 0;
i < layerCount; ++
i) {
95 if (!strcmp(layerName, layers[
i].layerName)) {
99 if (
version <= remove_patch_version(layers[
i].specVersion)) {
109static void print_backtrace() {
110#if defined(__GLIBC__)
113 backtrace_symbols_fd(stack,
count, 2);
125 const char* pLayerPrefix,
126 const char* pMessage,
130 if (strstr(pMessage,
"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01521") ||
131 strstr(pMessage,
"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01522")) {
135 if (strstr(pMessage,
"VUID-vkCmdDraw-None-02686") ||
136 strstr(pMessage,
"VUID-vkCmdDrawIndexed-None-02686")) {
139 SkDebugf(
"Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
144 SkDebugf(
"Vulkan warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
147 SkDebugf(
"Vulkan perf warning [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
150 SkDebugf(
"Vulkan info/debug [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
156#define ACQUIRE_VK_INST_PROC_LOCAL(name, instance) \
157 PFN_vk##name grVk##name = \
158 reinterpret_cast<PFN_vk##name>(getInstProc(instance, "vk" #name)); \
160 if (grVk##name == nullptr) { \
161 SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
167 uint32_t specVersion,
170 if (getInstProc ==
nullptr) {
174 ACQUIRE_VK_INST_PROC_LOCAL(EnumerateInstanceExtensionProperties,
VK_NULL_HANDLE);
175 ACQUIRE_VK_INST_PROC_LOCAL(EnumerateInstanceLayerProperties,
VK_NULL_HANDLE);
178 uint32_t layerCount = 0;
179#ifdef SK_ENABLE_VK_LAYERS
181 res = grVkEnumerateInstanceLayerProperties(&layerCount,
nullptr);
186 res = grVkEnumerateInstanceLayerProperties(&layerCount, layers);
192 uint32_t nonPatchVersion = remove_patch_version(specVersion);
193 for (
size_t i = 0;
i <
std::size(kDebugLayerNames); ++
i) {
194 int idx = should_include_debug_layer(kDebugLayerNames[
i], layerCount, layers,
197 instanceLayers->
push_back() = layers[idx];
206 uint32_t extensionCount = 0;
207 res = grVkEnumerateInstanceExtensionProperties(
nullptr, &extensionCount,
nullptr);
212 res = grVkEnumerateInstanceExtensionProperties(
nullptr, &extensionCount,
extensions);
217 for (uint32_t
i = 0;
i < extensionCount; ++
i) {
224 layerCount = instanceLayers->
size();
225 for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
226 uint32_t extensionCount = 0;
227 res = grVkEnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
228 &extensionCount,
nullptr);
233 res = grVkEnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
239 for (uint32_t
i = 0;
i < extensionCount; ++
i) {
248#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, device)
251 uint32_t specVersion, VkInstance
inst,
252 VkPhysicalDevice physDev,
255 if (getProc ==
nullptr) {
262 if (!EnumerateDeviceExtensionProperties ||
263 !EnumerateDeviceLayerProperties) {
269 uint32_t layerCount = 0;
270#ifdef SK_ENABLE_VK_LAYERS
271 res = EnumerateDeviceLayerProperties(physDev, &layerCount,
nullptr);
276 res = EnumerateDeviceLayerProperties(physDev, &layerCount, layers);
282 uint32_t nonPatchVersion = remove_patch_version(specVersion);
283 for (
size_t i = 0;
i <
std::size(kDebugLayerNames); ++
i) {
284 int idx = should_include_debug_layer(kDebugLayerNames[
i], layerCount, layers,
296 uint32_t extensionCount = 0;
297 res = EnumerateDeviceExtensionProperties(physDev,
nullptr, &extensionCount,
nullptr);
302 res = EnumerateDeviceExtensionProperties(physDev,
nullptr, &extensionCount,
extensions);
307 for (uint32_t
i = 0;
i < extensionCount; ++
i) {
314 layerCount = deviceLayers->
size();
315 for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
316 uint32_t extensionCount = 0;
317 res = EnumerateDeviceExtensionProperties(physDev,
318 (*deviceLayers)[layerIndex].layerName,
319 &extensionCount,
nullptr);
324 res = EnumerateDeviceExtensionProperties(physDev,
325 (*deviceLayers)[layerIndex].layerName,
331 for (uint32_t
i = 0;
i < extensionCount; ++
i) {
340#define ACQUIRE_VK_INST_PROC_NOCHECK(name, instance) \
341 PFN_vk##name grVk##name = reinterpret_cast<PFN_vk##name>(getInstProc(instance, "vk" #name))
343#define ACQUIRE_VK_INST_PROC(name, instance) \
344 PFN_vk##name grVk##name = \
345 reinterpret_cast<PFN_vk##name>(getInstProc(instance, "vk" #name)); \
347 if (grVk##name == nullptr) { \
348 SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
349 if (inst != VK_NULL_HANDLE) { \
350 destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension); \
356#define ACQUIRE_VK_PROC_NOCHECK(name, instance, device) \
357 PFN_vk##name grVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device))
359#define ACQUIRE_VK_PROC(name, instance, device) \
360 PFN_vk##name grVk##name = \
361 reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
363 if (grVk##name == nullptr) { \
364 SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
365 if (inst != VK_NULL_HANDLE) { \
366 destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension); \
372#define ACQUIRE_VK_PROC_LOCAL(name, instance, device) \
373 PFN_vk##name grVk##name = \
374 reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
376 if (grVk##name == nullptr) { \
377 SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
383 VkDebugReportCallbackEXT* debugCallback,
384 bool hasDebugExtension) {
386 ACQUIRE_VK_INST_PROC_LOCAL(DestroyDebugReportCallbackEXT,
inst);
387 grVkDestroyDebugReportCallbackEXT(
inst, *debugCallback,
nullptr);
390 ACQUIRE_VK_INST_PROC_LOCAL(DestroyInstance,
inst);
391 grVkDestroyInstance(
inst,
nullptr);
396 VkPhysicalDevice physDev, uint32_t physDeviceVersion,
403 void** tailPNext = &features->
pNext;
409 protectedMemoryFeatures =
412 protectedMemoryFeatures->
sType =
414 protectedMemoryFeatures->
pNext =
nullptr;
415 *tailPNext = protectedMemoryFeatures;
416 tailPNext = &protectedMemoryFeatures->
pNext;
424 blend->pNext =
nullptr;
426 tailPNext = &
blend->pNext;
435 ycbcrFeature->
pNext =
nullptr;
437 *tailPNext = ycbcrFeature;
438 tailPNext = &ycbcrFeature->
pNext;
443 grVkGetPhysicalDeviceFeatures2(physDev, features);
448 grVkGetPhysicalDeviceFeatures2KHR(physDev, features);
464 VkDebugReportCallbackEXT* debugCallback,
465 uint32_t* presentQueueIndexPtr,
466 const CanPresentFn& canPresent,
470 ACQUIRE_VK_INST_PROC_NOCHECK(EnumerateInstanceVersion,
VK_NULL_HANDLE);
471 uint32_t instanceVersion = 0;
472 if (!grVkEnumerateInstanceVersion) {
475 err = grVkEnumerateInstanceVersion(&instanceVersion);
477 SkDebugf(
"failed to enumerate instance version. Err: %d\n", err);
483 SkDebugf(
"protected requires vk instance version 1.1\n");
496 instanceVersion =
std::min(instanceVersion, apiVersion);
515 if (!init_instance_extensions_and_layers(getInstProc, instanceVersion,
523 for (
int i = 0;
i < instanceLayers.
size(); ++
i) {
524 instanceLayerNames.
push_back(instanceLayers[
i].layerName);
526 for (
int i = 0;
i < instanceExtensions.
size(); ++
i) {
527 if (strncmp(instanceExtensions[
i].extensionName,
"VK_KHX", 6) != 0) {
528 instanceExtensionNames.
push_back(instanceExtensions[
i].extensionName);
537 (uint32_t) instanceLayerNames.
size(),
538 instanceLayerNames.
begin(),
539 (uint32_t) instanceExtensionNames.
size(),
540 instanceExtensionNames.
begin(),
543 bool hasDebugExtension =
false;
546 err = grVkCreateInstance(&instance_create,
nullptr, &
inst);
548 SkDebugf(
"vkCreateInstance failed: %d\n", err);
552 ACQUIRE_VK_INST_PROC(GetDeviceProcAddr,
inst);
553 auto getProc = [getInstProc, grVkGetDeviceProcAddr](
const char* proc_name,
556 return grVkGetDeviceProcAddr(
device, proc_name);
558 return getInstProc(
instance, proc_name);
561#ifdef SK_ENABLE_VK_LAYERS
563 for (
int i = 0;
i < instanceExtensionNames.
size() && !hasDebugExtension; ++
i) {
565 hasDebugExtension =
true;
568 if (hasDebugExtension) {
572 callbackCreateInfo.
pNext =
nullptr;
578 callbackCreateInfo.
pfnCallback = &DebugReportCallback;
583 grVkCreateDebugReportCallbackEXT(
inst, &callbackCreateInfo,
nullptr, debugCallback);
597 err = grVkEnumeratePhysicalDevices(
inst, &gpuCount,
nullptr);
599 SkDebugf(
"vkEnumeratePhysicalDevices failed: %d\n", err);
600 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
604 SkDebugf(
"vkEnumeratePhysicalDevices returned no supported devices.\n");
605 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
611 physDevs.
resize(gpuCount);
612 err = grVkEnumeratePhysicalDevices(
inst, &gpuCount, physDevs.
data());
614 SkDebugf(
"vkEnumeratePhysicalDevices failed: %d\n", err);
615 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
620 VkPhysicalDevice physDev = physDevs.
front();
623 grVkGetPhysicalDeviceProperties(physDev, &physDeviceProperties);
627 SkDebugf(
"protected requires vk physical device version 1.1\n");
628 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
634 grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount,
nullptr);
636 SkDebugf(
"vkGetPhysicalDeviceQueueFamilyProperties returned no queues.\n");
637 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
645 grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps);
648 uint32_t graphicsQueueIndex = queueCount;
649 for (uint32_t
i = 0;
i < queueCount;
i++) {
651 graphicsQueueIndex =
i;
655 if (graphicsQueueIndex == queueCount) {
656 SkDebugf(
"Could not find any supported graphics queues.\n");
657 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
662 uint32_t presentQueueIndex = queueCount;
663 if (presentQueueIndexPtr && canPresent) {
664 for (uint32_t
i = 0;
i < queueCount;
i++) {
665 if (canPresent(
inst, physDev,
i)) {
666 presentQueueIndex =
i;
670 if (presentQueueIndex == queueCount) {
671 SkDebugf(
"Could not find any supported present queues.\n");
672 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
675 *presentQueueIndexPtr = presentQueueIndex;
679 presentQueueIndex = graphicsQueueIndex;
684 if (!init_device_extensions_and_layers(getProc, physDeviceVersion,
688 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
694 for (
int i = 0;
i < deviceLayers.
size(); ++
i) {
695 deviceLayerNames.
push_back(deviceLayers[
i].layerName);
701 bool hasKHRBufferDeviceAddress =
false;
702 for (
int i = 0;
i < deviceExtensions.
size(); ++
i) {
703 if (!strcmp(deviceExtensions[
i].extensionName,
"VK_KHR_buffer_device_address")) {
704 hasKHRBufferDeviceAddress =
true;
709 for (
int i = 0;
i < deviceExtensions.
size(); ++
i) {
713 if (0 != strncmp(deviceExtensions[
i].extensionName,
"VK_KHX", 6) &&
714 0 != strncmp(deviceExtensions[
i].extensionName,
"VK_NVX", 6)) {
719 if (0 == strcmp(deviceExtensions[
i].extensionName,
"VK_EXT_provoking_vertex") ||
720 0 == strcmp(deviceExtensions[
i].extensionName,
"VK_EXT_shader_object") ||
721 0 == strcmp(deviceExtensions[
i].extensionName,
"VK_KHR_dynamic_rendering") ||
722 0 == strcmp(deviceExtensions[
i].extensionName,
"VK_NV_acquire_winrt_display") ||
723 0 == strcmp(deviceExtensions[
i].extensionName,
"VK_NV_cuda_kernel_launch") ||
724 0 == strcmp(deviceExtensions[
i].extensionName,
"VK_NV_low_latency") ||
725 0 == strcmp(deviceExtensions[
i].extensionName,
"VK_NV_present_barrier")) {
729 if (!hasKHRBufferDeviceAddress ||
730 0 != strcmp(deviceExtensions[
i].extensionName,
"VK_EXT_buffer_device_address")) {
731 deviceExtensionNames.
push_back(deviceExtensions[
i].extensionName);
737 (uint32_t) instanceExtensionNames.
size(),
738 instanceExtensionNames.
begin(),
739 (uint32_t) deviceExtensionNames.
size(),
740 deviceExtensionNames.
begin());
744 features->
pNext =
nullptr;
747 void* pointerToFeatures =
nullptr;
750 if (!setup_features(getProc,
inst, physDev, physDeviceVersion,
extensions, features,
752 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
758 pointerToFeatures = features;
760 grVkGetPhysicalDeviceFeatures(physDev, deviceFeatures);
768 float queuePriorities[1] = { 0.0 };
790 uint32_t queueInfoCount = (presentQueueIndex != graphicsQueueIndex) ? 2 : 1;
798 (uint32_t) deviceLayerNames.
size(),
799 deviceLayerNames.
begin(),
800 (uint32_t) deviceExtensionNames.
size(),
801 deviceExtensionNames.
begin(),
802 pointerToFeatures ? nullptr : deviceFeatures
806#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
808 __lsan::ScopedDisabler lsanDisabler;
810 err = grVkCreateDevice(physDev, &deviceInfo,
nullptr, &
device);
813 SkDebugf(
"CreateDevice failed: %d\n", err);
814 destroy_instance(getInstProc,
inst, debugCallback, hasDebugExtension);
820 ACQUIRE_VK_PROC(GetDeviceQueue2,
inst,
device);
821 SkASSERT(grVkGetDeviceQueue2 !=
nullptr);
831 grVkGetDeviceQueue(
device, graphicsQueueIndex, 0, &
queue);
860 struct CommonVulkanHeader {
865 void* pNext = features->
pNext;
867 void* current = pNext;
868 pNext =
static_cast<CommonVulkanHeader*
>(current)->pNext;
#define GET_PROC_LOCAL(F)
#define ACQUIRE_VK_PROC_LOCAL(name, inst)
#define SkDEBUGFAIL(message)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SK_API void sk_free(void *)
static void * sk_malloc_throw(size_t size)
void * SkGetProcedureAddress(void *library, const char *functionName)
void * SkLoadDynamicLibrary(const char *libraryName)
static sk_sp< VulkanMemoryAllocator > Make(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, uint32_t physicalDeviceVersion, const skgpu::VulkanExtensions *extensions, const skgpu::VulkanInterface *interface)
void resize(size_t count)
FlutterSemanticsFlag flags
static SkColor blend(SkColor dst, SkColor src, void(*mode)(float, float, float, float *, float *, float *))
static float min(float r, float g, float b)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
std::function< PFN_vkVoidFunction(const char *, VkInstance, VkDevice)> VulkanGetProc
PFN_vkDebugReportCallbackEXT pfnCallback
VkDebugReportFlagsEXT flags
VkPhysicalDeviceFeatures features
VkBool32 robustBufferAccess
VkBool32 samplerYcbcrConversion
const VkPhysicalDeviceFeatures2 * fDeviceFeatures2
Protected fProtectedContext
sk_sp< VulkanMemoryAllocator > fMemoryAllocator
uint32_t fGraphicsQueueIndex
skgpu::VulkanGetProc fGetProc
VkPhysicalDevice fPhysicalDevice
const skgpu::VulkanExtensions * fVkExtensions
@ VK_DEBUG_REPORT_WARNING_BIT_EXT
@ VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT
@ VK_DEBUG_REPORT_ERROR_BIT_EXT
#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME
VkFlags VkDeviceQueueCreateFlags
@ VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
VkDebugReportObjectTypeEXT
#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME
#define VK_MAKE_VERSION(major, minor, patch)
#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME
#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME
VkFlags VkDebugReportFlagsEXT
PFN_vkVoidFunction(VKAPI_PTR * PFN_vkGetInstanceProcAddr)(VkInstance instance, const char *pName)
@ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES
@ VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2
@ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES
@ VK_STRUCTURE_TYPE_APPLICATION_INFO
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT
@ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2
@ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO