diff --git a/include/gpu/vk/GrVkBackendContext.h b/include/gpu/vk/GrVkBackendContext.h index f49c36f7e3..8617603041 100644 --- a/include/gpu/vk/GrVkBackendContext.h +++ b/include/gpu/vk/GrVkBackendContext.h @@ -49,7 +49,10 @@ struct SK_API GrVkBackendContext { VkQueue fQueue; uint32_t fGraphicsQueueIndex; uint32_t fMinAPIVersion; // Deprecated. Set fInstanceVersion instead. - uint32_t fInstanceVersion = 0; + uint32_t fInstanceVersion = 0; // Deprecated. Set fMaxApiVersion instead. + // The max api version set here should match the value set in VkApplicationInfo::apiVersion when + // then VkInstance was created. + uint32_t fMaxAPIVersion = 0; uint32_t fExtensions = 0; // Deprecated. Use fVkExtensions instead. const GrVkExtensions* fVkExtensions = nullptr; uint32_t fFeatures; // Deprecated. Use either fDeviceFeatures[2] instead. diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index e115ea06e5..a720e72bf1 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -18,7 +18,8 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features, - uint32_t instanceVersion, const GrVkExtensions& extensions) + uint32_t instanceVersion, uint32_t physicalDeviceVersion, + const GrVkExtensions& extensions) : INHERITED(contextOptions) { /************************************************************************** @@ -48,7 +49,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* fShaderCaps.reset(new GrShaderCaps(contextOptions)); - this->init(contextOptions, vkInterface, physDev, features, extensions); + this->init(contextOptions, vkInterface, physDev, features, physicalDeviceVersion, extensions); } bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, @@ -230,7 +231,7 @@ template T* get_extension_feature_struct(const VkPhysicalDeviceFeatu void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features, - const GrVkExtensions& extensions) { + uint32_t physicalDeviceVersion, const GrVkExtensions& extensions) { VkPhysicalDeviceProperties properties; GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties)); @@ -238,7 +239,7 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* VkPhysicalDeviceMemoryProperties memoryProperties; GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties)); - uint32_t physicalDeviceVersion = properties.apiVersion; + SkASSERT(physicalDeviceVersion <= properties.apiVersion); if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) || extensions.hasExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1)) { diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h index 79bd7d45b6..2309541090 100644 --- a/src/gpu/vk/GrVkCaps.h +++ b/src/gpu/vk/GrVkCaps.h @@ -29,7 +29,8 @@ public: */ GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, VkPhysicalDevice device, const VkPhysicalDeviceFeatures2& features, - uint32_t instanceVersion, const GrVkExtensions& extensions); + uint32_t instanceVersion, uint32_t physicalDeviceVersion, + const GrVkExtensions& extensions); bool isConfigTexturable(GrPixelConfig config) const override { return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags); @@ -165,7 +166,8 @@ private: }; void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, - VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, const GrVkExtensions&); + VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, + uint32_t physicalDeviceVersion, const GrVkExtensions&); void initGrCaps(const GrVkInterface* vkInterface, VkPhysicalDevice physDev, const VkPhysicalDeviceProperties&, diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 142c1c77a2..0c0c5cd0da 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -68,6 +68,21 @@ sk_sp GrVkGpu::Make(const GrVkBackendContext& backendContext, return nullptr; } + PFN_vkEnumerateInstanceVersion localEnumerateInstanceVersion = + reinterpret_cast( + backendContext.fGetProc("vkEnumerateInstanceVersion", + VK_NULL_HANDLE, VK_NULL_HANDLE)); + uint32_t instanceVersion = 0; + if (!localEnumerateInstanceVersion) { + instanceVersion = VK_MAKE_VERSION(1, 0, 0); + } else { + VkResult err = localEnumerateInstanceVersion(&instanceVersion); + if (err) { + SkDebugf("Failed to enumerate instance version. Err: %d\n", err); + return nullptr; + } + } + PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties = reinterpret_cast( backendContext.fGetProc("vkGetPhysicalDeviceProperties", @@ -81,17 +96,22 @@ sk_sp GrVkGpu::Make(const GrVkBackendContext& backendContext, localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &physDeviceProperties); uint32_t physDevVersion = physDeviceProperties.apiVersion; + uint32_t apiVersion = backendContext.fMaxAPIVersion ? backendContext.fMaxAPIVersion + : instanceVersion; + + instanceVersion = SkTMin(instanceVersion, apiVersion); + physDevVersion = SkTMin(physDevVersion, apiVersion); + sk_sp interface; if (backendContext.fVkExtensions) { interface.reset(new GrVkInterface(backendContext.fGetProc, backendContext.fInstance, backendContext.fDevice, - backendContext.fInstanceVersion, + instanceVersion, physDevVersion, backendContext.fVkExtensions)); - if (!interface->validate(backendContext.fInstanceVersion, physDevVersion, - backendContext.fVkExtensions)) { + if (!interface->validate(instanceVersion, physDevVersion, backendContext.fVkExtensions)) { return nullptr; } } else { @@ -101,21 +121,23 @@ sk_sp GrVkGpu::Make(const GrVkBackendContext& backendContext, interface.reset(new GrVkInterface(backendContext.fGetProc, backendContext.fInstance, backendContext.fDevice, - backendContext.fInstanceVersion, + instanceVersion, physDevVersion, &extensions)); - if (!interface->validate(backendContext.fInstanceVersion, physDevVersion, &extensions)) { + if (!interface->validate(instanceVersion, physDevVersion, &extensions)) { return nullptr; } } - return sk_sp(new GrVkGpu(context, options, backendContext, interface)); + return sk_sp(new GrVkGpu(context, options, backendContext, interface, instanceVersion, + physDevVersion)); } //////////////////////////////////////////////////////////////////////////////// GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, - const GrVkBackendContext& backendContext, sk_sp interface) + const GrVkBackendContext& backendContext, sk_sp interface, + uint32_t instanceVersion, uint32_t physicalDeviceVersion) : INHERITED(context) , fInterface(std::move(interface)) , fMemoryAllocator(backendContext.fMemoryAllocator) @@ -136,19 +158,18 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, fCompiler = new SkSL::Compiler(); - uint32_t instanceVersion = backendContext.fInstanceVersion ? backendContext.fInstanceVersion - : backendContext.fMinAPIVersion; - if (backendContext.fDeviceFeatures2) { fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice, *backendContext.fDeviceFeatures2, instanceVersion, + physicalDeviceVersion, *backendContext.fVkExtensions)); } else if (backendContext.fDeviceFeatures) { VkPhysicalDeviceFeatures2 features2; features2.pNext = nullptr; features2.features = *backendContext.fDeviceFeatures; fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice, - features2, instanceVersion, *backendContext.fVkExtensions)); + features2, instanceVersion, physicalDeviceVersion, + *backendContext.fVkExtensions)); } else { VkPhysicalDeviceFeatures2 features; memset(&features, 0, sizeof(VkPhysicalDeviceFeatures2)); @@ -163,7 +184,8 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options, features.features.sampleRateShading = true; } fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice, - features, instanceVersion, GrVkExtensions())); + features, instanceVersion, physicalDeviceVersion, + GrVkExtensions())); } fCaps.reset(SkRef(fVkCaps.get())); diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index 671549e4d4..7888557844 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -175,7 +175,7 @@ public: private: GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext&, - sk_sp); + sk_sp, uint32_t instanceVersion, uint32_t physicalDeviceVersion); void onResetContext(uint32_t resetBits) override {} diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp index 9888df3e66..ed6549c42a 100644 --- a/tools/gpu/vk/VkTestUtils.cpp +++ b/tools/gpu/vk/VkTestUtils.cpp @@ -397,6 +397,16 @@ bool CreateVkBackendContext(GrVkGetProc getProc, } } SkASSERT(instanceVersion >= VK_MAKE_VERSION(1, 0, 0)); + uint32_t apiVersion = VK_MAKE_VERSION(1, 0, 0); + if (instanceVersion >= VK_MAKE_VERSION(1, 1, 0)) { + // If the instance version is 1.0 we must have the apiVersion also be 1.0. However, if the + // instance version is 1.1 or higher, we can set the apiVersion to be whatever the highest + // api we may use in skia (technically it can be arbitrary). So for now we set it to 1.1 + // since that is the highest vulkan version. + apiVersion = VK_MAKE_VERSION(1, 1, 0); + } + + instanceVersion = SkTMin(instanceVersion, apiVersion); VkPhysicalDevice physDev; VkDevice device; @@ -409,7 +419,7 @@ bool CreateVkBackendContext(GrVkGetProc getProc, 0, // applicationVersion "vktest", // pEngineName 0, // engineVerison - instanceVersion, // apiVersion + apiVersion, // apiVersion }; SkTArray instanceLayers; @@ -512,7 +522,7 @@ bool CreateVkBackendContext(GrVkGetProc getProc, VkPhysicalDeviceProperties physDeviceProperties; grVkGetPhysicalDeviceProperties(physDev, &physDeviceProperties); - int physDeviceVersion = physDeviceProperties.apiVersion; + int physDeviceVersion = SkTMin(physDeviceProperties.apiVersion, apiVersion); // query to get the initial queue props size uint32_t queueCount; @@ -666,7 +676,7 @@ bool CreateVkBackendContext(GrVkGetProc getProc, ctx->fDevice = device; ctx->fQueue = queue; ctx->fGraphicsQueueIndex = graphicsQueueIndex; - ctx->fInstanceVersion = instanceVersion; + ctx->fMaxAPIVersion = apiVersion; ctx->fVkExtensions = extensions; ctx->fDeviceFeatures2 = features; ctx->fGetProc = getProc;