Skip to content

Commit

Permalink
Start adding support for some base extensions which others build on.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
egdaniel authored and Skia Commit-Bot committed Aug 6, 2018
1 parent 12fb9cf commit c0b03d8
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 12 deletions.
11 changes: 11 additions & 0 deletions include/gpu/vk/GrVkExtensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ class SK_API GrVkExtensions {
};
};

#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);

Expand Down
41 changes: 38 additions & 3 deletions src/gpu/vk/GrVkCaps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,24 @@
#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;
fMustSleepOnTearDown = false;
fNewCBOnPipelineChange = false;
fShouldAlwaysUseDedicatedImageMemory = false;

fSupportsPhysicalDeviceProperties2 = false;
fSupportsMemoryRequirements2 = false;
fSupportsMaintenance1 = false;
fSupportsMaintenance2 = false;
fSupportsMaintenance3 = false;

/**************************************************************************
* GrDrawTargetCaps fields
**************************************************************************/
Expand All @@ -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,
Expand Down Expand Up @@ -196,14 +203,42 @@ 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));

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);

Expand Down
23 changes: 20 additions & 3 deletions src/gpu/vk/GrVkCaps.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -28,7 +29,7 @@ class GrVkCaps : public GrCaps {
*/
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);
Expand Down Expand Up @@ -104,6 +105,16 @@ class GrVkCaps : public GrCaps {
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
Expand Down Expand Up @@ -147,7 +158,7 @@ class GrVkCaps : public GrCaps {
};

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&);
Expand Down Expand Up @@ -193,6 +204,12 @@ class GrVkCaps : public GrCaps {
bool fNewCBOnPipelineChange;
bool fShouldAlwaysUseDedicatedImageMemory;

bool fSupportsPhysicalDeviceProperties2;
bool fSupportsMemoryRequirements2;
bool fSupportsMaintenance1;
bool fSupportsMaintenance2;
bool fSupportsMaintenance3;

typedef GrCaps INHERITED;
};

Expand Down
28 changes: 24 additions & 4 deletions src/gpu/vk/GrVkGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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()));

Expand Down
94 changes: 93 additions & 1 deletion src/gpu/vk/GrVkInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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 ||
Expand Down Expand Up @@ -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;
}

25 changes: 24 additions & 1 deletion src/gpu/vk/GrVkInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ struct GrVkInterface : public SkRefCnt {
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
Expand Down Expand Up @@ -188,6 +191,26 @@ struct GrVkInterface : public SkRefCnt {
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;
};

Expand Down
Loading

0 comments on commit c0b03d8

Please sign in to comment.