Start adding support for some base extensions which others build on.

Many of the other extensions in Vulkan rely on these some just want to
get these landed so we can start building on top of them.

Bug: skia:
Change-Id: Icef82c169cd50ff51b97fe065923531ef2940319
Reviewed-on: https://skia-review.googlesource.com/145362
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Greg Daniel 2018-08-03 14:41:15 -04:00 committed by Skia Commit-Bot
parent 12fb9cfeee
commit c0b03d8dfc
7 changed files with 224 additions and 12 deletions

View File

@ -43,6 +43,17 @@ public:
};
};
#ifdef SK_DEBUG
void dump() const {
SkDebugf("**Vulkan Extensions**\n");
for (int i = 0; i < fExtensions.count(); ++i) {
SkDebugf("%s. Version: %d\n",
fExtensions[i].fName.c_str(), fExtensions[i].fSpecVersion);
}
SkDebugf("**End Vulkan Extensions**\n");
}
#endif
private:
void getSpecVersions(GrVkGetProc getProc, VkInstance, VkPhysicalDevice);

View File

@ -13,10 +13,11 @@
#include "GrVkInterface.h"
#include "GrVkUtil.h"
#include "vk/GrVkBackendContext.h"
#include "vk/GrVkExtensions.h"
GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures& features,
uint32_t instanceVersion)
uint32_t instanceVersion, const GrVkExtensions& extensions)
: INHERITED(contextOptions) {
fMustDoCopiesFromOrigin = false;
fMustSubmitCommandsBeforeCopyOp = false;
@ -24,6 +25,12 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
fNewCBOnPipelineChange = false;
fShouldAlwaysUseDedicatedImageMemory = false;
fSupportsPhysicalDeviceProperties2 = false;
fSupportsMemoryRequirements2 = false;
fSupportsMaintenance1 = false;
fSupportsMaintenance2 = false;
fSupportsMaintenance3 = false;
/**************************************************************************
* GrDrawTargetCaps fields
**************************************************************************/
@ -48,7 +55,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
fShaderCaps.reset(new GrShaderCaps(contextOptions));
this->init(contextOptions, vkInterface, physDev, features);
this->init(contextOptions, vkInterface, physDev, features, extensions);
}
bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
@ -196,7 +203,8 @@ bool GrVkCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* s
}
void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures& features) {
VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures& features,
const GrVkExtensions& extensions) {
VkPhysicalDeviceProperties properties;
GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
@ -204,6 +212,33 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface*
VkPhysicalDeviceMemoryProperties memoryProperties;
GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties));
uint32_t physicalDeviceVersion = properties.apiVersion;
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions.hasExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1)) {
fSupportsPhysicalDeviceProperties2 = true;
}
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions.hasExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, 1)) {
fSupportsMemoryRequirements2 = true;
}
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions.hasExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1)) {
fSupportsMaintenance1 = true;
}
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions.hasExtension(VK_KHR_MAINTENANCE2_EXTENSION_NAME, 1)) {
fSupportsMaintenance2 = true;
}
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions.hasExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME, 1)) {
fSupportsMaintenance3 = true;
}
this->initGrCaps(properties, memoryProperties, features);
this->initShaderCaps(properties, features);

View File

@ -12,8 +12,9 @@
#include "GrVkStencilAttachment.h"
#include "vk/GrVkDefines.h"
struct GrVkInterface;
class GrShaderCaps;
class GrVkExtensions;
struct GrVkInterface;
/**
* Stores some capabilities of a Vk backend.
@ -28,7 +29,7 @@ public:
*/
GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice device, const VkPhysicalDeviceFeatures& features,
uint32_t instanceVersion);
uint32_t instanceVersion, const GrVkExtensions& extensions);
bool isConfigTexturable(GrPixelConfig config) const override {
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
@ -104,6 +105,16 @@ public:
return fPreferedStencilFormat;
}
// Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct.
bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; }
// Returns whether the device supports the ability to extend VkMemoryRequirements struct.
bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; }
// Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In
// Vulkan 1.1 all these maintenance are part of the core spec.
bool supportsMaintenance1() const { return fSupportsMaintenance1; }
bool supportsMaintenance2() const { return fSupportsMaintenance2; }
bool supportsMaintenance3() const { return fSupportsMaintenance3; }
/**
* Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
* the surface is not a render target, otherwise it is the number of samples in the render
@ -147,7 +158,7 @@ private:
};
void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice device, const VkPhysicalDeviceFeatures&);
VkPhysicalDevice device, const VkPhysicalDeviceFeatures&, const GrVkExtensions&);
void initGrCaps(const VkPhysicalDeviceProperties&,
const VkPhysicalDeviceMemoryProperties&,
const VkPhysicalDeviceFeatures&);
@ -193,6 +204,12 @@ private:
bool fNewCBOnPipelineChange;
bool fShouldAlwaysUseDedicatedImageMemory;
bool fSupportsPhysicalDeviceProperties2;
bool fSupportsMemoryRequirements2;
bool fSupportsMaintenance1;
bool fSupportsMaintenance2;
bool fSupportsMaintenance3;
typedef GrCaps INHERITED;
};

View File

@ -66,14 +66,30 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
return nullptr;
}
PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
backendContext.fGetProc("vkGetPhysicalDeviceProperties",
backendContext.fInstance,
VK_NULL_HANDLE));
if (!localGetPhysicalDeviceProperties) {
return nullptr;
}
VkPhysicalDeviceProperties physDeviceProperties;
localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &physDeviceProperties);
uint32_t physDevVersion = physDeviceProperties.apiVersion;
sk_sp<const GrVkInterface> interface;
if (backendContext.fVkExtensions) {
interface.reset(new GrVkInterface(backendContext.fGetProc,
backendContext.fInstance,
backendContext.fDevice,
backendContext.fInstanceVersion,
physDevVersion,
backendContext.fVkExtensions));
if (!interface->validate(backendContext.fVkExtensions)) {
if (!interface->validate(backendContext.fInstanceVersion, physDevVersion,
backendContext.fVkExtensions)) {
return nullptr;
}
} else {
@ -83,8 +99,10 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
interface.reset(new GrVkInterface(backendContext.fGetProc,
backendContext.fInstance,
backendContext.fDevice,
backendContext.fInstanceVersion,
physDevVersion,
&extensions));
if (!interface->validate(&extensions)) {
if (!interface->validate(backendContext.fInstanceVersion, physDevVersion, &extensions)) {
return nullptr;
}
}
@ -118,8 +136,10 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
: backendContext.fMinAPIVersion;
if (backendContext.fFeatures & kIgnoreAllFlags_GrVkFeatureFlag) {
SkASSERT(backendContext.fVkExtensions);
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
backendContext.fDeviceFeatures, instanceVersion));
backendContext.fDeviceFeatures, instanceVersion,
*backendContext.fVkExtensions));
} else {
VkPhysicalDeviceFeatures features;
if (backendContext.fFeatures & kGeometryShader_GrVkFeatureFlag) {
@ -132,7 +152,7 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
features.sampleRateShading = true;
}
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
features, instanceVersion));
features, instanceVersion, GrVkExtensions()));
}
fCaps.reset(SkRef(fVkCaps.get()));

View File

@ -13,9 +13,14 @@
#define ACQUIRE_PROC(name, instance, device) fFunctions.f##name = \
reinterpret_cast<PFN_vk##name>(getProc("vk"#name, instance, device));
#define ACQUIRE_PROC_SUFFIX(name, suffix, instance, device) fFunctions.f##name = \
reinterpret_cast<PFN_vk##name##suffix>(getProc("vk"#name#suffix, instance, device));
GrVkInterface::GrVkInterface(GrVkGetProc getProc,
VkInstance instance,
VkDevice device,
uint32_t instanceVersion,
uint32_t physicalDeviceVersion,
const GrVkExtensions* extensions) {
if (getProc == nullptr) {
return;
@ -160,6 +165,52 @@ GrVkInterface::GrVkInterface(GrVkGetProc getProc,
ACQUIRE_PROC(CmdNextSubpass, VK_NULL_HANDLE, device);
ACQUIRE_PROC(CmdEndRenderPass, VK_NULL_HANDLE, device);
ACQUIRE_PROC(CmdExecuteCommands, VK_NULL_HANDLE, device);
// Functions for VK_KHR_get_physical_device_properties2
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
ACQUIRE_PROC(GetPhysicalDeviceFeatures2, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(GetPhysicalDeviceProperties2, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(GetPhysicalDeviceFormatProperties2, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(GetPhysicalDeviceImageFormatProperties2, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(GetPhysicalDeviceQueueFamilyProperties2, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(GetPhysicalDeviceMemoryProperties2, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(GetPhysicalDeviceSparseImageFormatProperties2, instance, VK_NULL_HANDLE);
} else if (extensions->hasExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
1)) {
ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceFeatures2, KHR, instance, VK_NULL_HANDLE);
ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceProperties2, KHR, instance, VK_NULL_HANDLE);
ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceFormatProperties2, KHR, instance, VK_NULL_HANDLE);
ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceImageFormatProperties2, KHR, instance, VK_NULL_HANDLE);
ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceQueueFamilyProperties2, KHR, instance, VK_NULL_HANDLE);
ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceMemoryProperties2, KHR, instance, VK_NULL_HANDLE);
ACQUIRE_PROC_SUFFIX(GetPhysicalDeviceSparseImageFormatProperties2, KHR, instance,
VK_NULL_HANDLE);
}
// Functions for VK_KHR_get_memory_requirements2
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
ACQUIRE_PROC(GetImageMemoryRequirements2, VK_NULL_HANDLE, device);
ACQUIRE_PROC(GetBufferMemoryRequirements2, VK_NULL_HANDLE, device);
ACQUIRE_PROC(GetImageSparseMemoryRequirements2, VK_NULL_HANDLE, device);
} else if (extensions->hasExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, 1)) {
ACQUIRE_PROC_SUFFIX(GetImageMemoryRequirements2, KHR, VK_NULL_HANDLE, device);
ACQUIRE_PROC_SUFFIX(GetBufferMemoryRequirements2, KHR, VK_NULL_HANDLE, device);
ACQUIRE_PROC_SUFFIX(GetImageSparseMemoryRequirements2, KHR, VK_NULL_HANDLE, device);
}
// Functions for VK_KHR_maintenance1 or vulkan 1.1
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
ACQUIRE_PROC(TrimCommandPool, VK_NULL_HANDLE, device);
} else if (extensions->hasExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1)) {
ACQUIRE_PROC_SUFFIX(TrimCommandPool, KHR, VK_NULL_HANDLE, device);
}
// Functions for VK_KHR_maintenance3 or vulkan 1.1
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
ACQUIRE_PROC(GetDescriptorSetLayoutSupport, VK_NULL_HANDLE, device);
} else if (extensions->hasExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME, 1)) {
ACQUIRE_PROC_SUFFIX(GetDescriptorSetLayoutSupport, KHR, VK_NULL_HANDLE, device);
}
}
#ifdef SK_DEBUG
@ -172,7 +223,8 @@ GrVkInterface::GrVkInterface(GrVkGetProc getProc,
if (kIsDebug) { SkDebugf("%s:%d GrVkInterface::validate() failed.\n", __FILE__, __LINE__); } \
return false;
bool GrVkInterface::validate(const GrVkExtensions* extensions) const {
bool GrVkInterface::validate(uint32_t instanceVersion, uint32_t physicalDeviceVersion,
const GrVkExtensions* extensions) const {
// functions that are always required
if (nullptr == fFunctions.fCreateInstance ||
nullptr == fFunctions.fDestroyInstance ||
@ -312,6 +364,46 @@ bool GrVkInterface::validate(const GrVkExtensions* extensions) const {
RETURN_FALSE_INTERFACE
}
// Functions for VK_KHR_get_physical_device_properties2 or vulkan 1.1
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions->hasExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1)) {
if (nullptr == fFunctions.fGetPhysicalDeviceFeatures2 ||
nullptr == fFunctions.fGetPhysicalDeviceProperties2 ||
nullptr == fFunctions.fGetPhysicalDeviceFormatProperties2 ||
nullptr == fFunctions.fGetPhysicalDeviceImageFormatProperties2 ||
nullptr == fFunctions.fGetPhysicalDeviceQueueFamilyProperties2 ||
nullptr == fFunctions.fGetPhysicalDeviceMemoryProperties2 ||
nullptr == fFunctions.fGetPhysicalDeviceSparseImageFormatProperties2) {
RETURN_FALSE_INTERFACE
}
}
// Functions for VK_KHR_get_memory_requirements2 or vulkan 1.1
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions->hasExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, 1)) {
if (nullptr == fFunctions.fGetImageMemoryRequirements2 ||
nullptr == fFunctions.fGetBufferMemoryRequirements2 ||
nullptr == fFunctions.fGetImageSparseMemoryRequirements2) {
RETURN_FALSE_INTERFACE
}
}
// Functions for VK_KHR_maintenance1 or vulkan 1.1
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions->hasExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1)) {
if (nullptr == fFunctions.fTrimCommandPool) {
RETURN_FALSE_INTERFACE
}
}
// Functions for VK_KHR_maintenance3 or vulkan 1.1
if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
extensions->hasExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME, 1)) {
if (nullptr == fFunctions.fGetDescriptorSetLayoutSupport) {
RETURN_FALSE_INTERFACE
}
}
return true;
}

View File

@ -42,11 +42,14 @@ public:
GrVkInterface(GrVkGetProc getProc,
VkInstance instance,
VkDevice device,
uint32_t instanceVersion,
uint32_t physicalDeviceVersion,
const GrVkExtensions*);
// Validates that the GrVkInterface supports its advertised standard. This means the necessary
// function pointers have been initialized for Vulkan version.
bool validate(const GrVkExtensions*) const;
bool validate(uint32_t instanceVersion, uint32_t physicalDeviceVersion,
const GrVkExtensions*) const;
/**
* The function pointers are in a struct so that we can have a compiler generated assignment
@ -188,6 +191,26 @@ public:
VkPtr<PFN_vkCmdNextSubpass> fCmdNextSubpass;
VkPtr<PFN_vkCmdEndRenderPass> fCmdEndRenderPass;
VkPtr<PFN_vkCmdExecuteCommands> fCmdExecuteCommands;
// Functions for VK_KHR_get_physical_device_properties2 or vulkan 1.1
VkPtr<PFN_vkGetPhysicalDeviceFeatures2> fGetPhysicalDeviceFeatures2;
VkPtr<PFN_vkGetPhysicalDeviceProperties2> fGetPhysicalDeviceProperties2;
VkPtr<PFN_vkGetPhysicalDeviceFormatProperties2> fGetPhysicalDeviceFormatProperties2;
VkPtr<PFN_vkGetPhysicalDeviceImageFormatProperties2> fGetPhysicalDeviceImageFormatProperties2;
VkPtr<PFN_vkGetPhysicalDeviceQueueFamilyProperties2> fGetPhysicalDeviceQueueFamilyProperties2;
VkPtr<PFN_vkGetPhysicalDeviceMemoryProperties2> fGetPhysicalDeviceMemoryProperties2;
VkPtr<PFN_vkGetPhysicalDeviceSparseImageFormatProperties2> fGetPhysicalDeviceSparseImageFormatProperties2;
// Functions for VK_KHR_get_memory_requirements2 or vulkan 1.1
VkPtr<PFN_vkGetImageMemoryRequirements2> fGetImageMemoryRequirements2;
VkPtr<PFN_vkGetBufferMemoryRequirements2> fGetBufferMemoryRequirements2;
VkPtr<PFN_vkGetImageSparseMemoryRequirements2> fGetImageSparseMemoryRequirements2;
// Functions for VK_KHR_maintenance1 or vulkan 1.1
VkPtr<PFN_vkTrimCommandPool> fTrimCommandPool;
// Functions for VK_KHR_maintenance3 or vulkan 1.1
VkPtr<PFN_vkGetDescriptorSetLayoutSupport> fGetDescriptorSetLayoutSupport;
} fFunctions;
};

View File

@ -76,7 +76,21 @@ void VulkanWindowContext::initializeContext() {
fDevice = backendContext.fDevice;
fGraphicsQueueIndex = backendContext.fGraphicsQueueIndex;
fGraphicsQueue = backendContext.fQueue;
PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
backendContext.fGetProc("vkGetPhysicalDeviceProperties",
backendContext.fInstance,
VK_NULL_HANDLE));
if (!localGetPhysicalDeviceProperties) {
return;
}
VkPhysicalDeviceProperties physDeviceProperties;
localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &physDeviceProperties);
uint32_t physDevVersion = physDeviceProperties.apiVersion;
fInterface.reset(new GrVkInterface(backendContext.fGetProc, fInstance, fDevice,
backendContext.fInstanceVersion, physDevVersion,
&extensions));
GET_PROC(DestroyInstance);