Revert "Reland "Let client pass in full extension to GrVkBackendContext.""

This reverts commit a782dcb3c4.

Reason for revert: fuchsia changes reverted

Original change's description:
> Reland "Let client pass in full extension to GrVkBackendContext."
> 
> This reverts commit cb92b26e5c.
> 
> Reason for revert: <INSERT REASONING HERE>
> 
> Original change's description:
> > Revert "Let client pass in full extension to GrVkBackendContext."
> > 
> > This reverts commit 45c9dab4c3.
> > 
> > Reason for revert: fucshia uses GrVkBackendContext. Need to revert earlier changes
> > 
> > Original change's description:
> > > Let client pass in full extension to GrVkBackendContext.
> > > 
> > > Bug: skia:
> > > Change-Id: I772ab4ccbca0f4f7e7d429d6c421b07d97f0606f
> > > Reviewed-on: https://skia-review.googlesource.com/131880
> > > Reviewed-by: Jim Van Verth <jvanverth@google.com>
> > > Commit-Queue: Greg Daniel <egdaniel@google.com>
> > 
> > TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com
> > 
> > Change-Id: I1a765ff406c83cb234c3614b804fbed677d5a382
> > No-Presubmit: true
> > No-Tree-Checks: true
> > No-Try: true
> > Bug: skia:
> > Reviewed-on: https://skia-review.googlesource.com/137901
> > Reviewed-by: Greg Daniel <egdaniel@google.com>
> > Commit-Queue: Greg Daniel <egdaniel@google.com>
> 
> TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com
> 
> # Not skipping CQ checks because original CL landed > 1 day ago.
> 
> Bug: skia:
> Change-Id: I0af797c51dde705473e9afaccb1d4b4423e8c41e
> Reviewed-on: https://skia-review.googlesource.com/138302
> Commit-Queue: Greg Daniel <egdaniel@google.com>
> Reviewed-by: Greg Daniel <egdaniel@google.com>

TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com

Change-Id: Idf760d5ac6b82df33a4408079a0223be833058ad
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/138420
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2018-06-28 23:29:35 +00:00 committed by Skia Commit-Bot
parent 2423b5d2d3
commit dc13c21b1e
13 changed files with 368 additions and 393 deletions

View File

@ -537,7 +537,6 @@ skia_null_gpu_sources = []
skia_vk_sources = [
"$_include/gpu/vk/GrVkBackendContext.h",
"$_include/gpu/vk/GrVkDefines.h",
"$_include/gpu/vk/GrVkExtensions.h",
"$_include/gpu/vk/GrVkInterface.h",
"$_include/gpu/vk/GrVkMemoryAllocator.h",
"$_include/gpu/vk/GrVkTypes.h",
@ -563,6 +562,7 @@ skia_vk_sources = [
"$_src/gpu/vk/GrVkDescriptorSetManager.cpp",
"$_src/gpu/vk/GrVkDescriptorSetManager.h",
"$_src/gpu/vk/GrVkExtensions.cpp",
"$_src/gpu/vk/GrVkExtensions.h",
"$_src/gpu/vk/GrVkFramebuffer.cpp",
"$_src/gpu/vk/GrVkFramebuffer.h",
"$_src/gpu/vk/GrVkGpu.cpp",

View File

@ -49,6 +49,7 @@ struct SK_API GrVkBackendContext {
uint32_t fFeatures;
sk_sp<const GrVkInterface> fInterface;
sk_sp<GrVkMemoryAllocator> fMemoryAllocator;
// This is deprecated and should be set to false. The client is responsible for managing the
// lifetime of the VkInstance and VkDevice objects.
bool fOwnsInstanceAndDevice = false;

View File

@ -1,35 +0,0 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrVkExtensions_DEFINED
#define GrVkExtensions_DEFINED
#include "../private/SkTArray.h"
#include "SkString.h"
/**
* Helper class that eats in an array of extensions strings for instance and device and allows for
* quicker querying if an extension is present.
*/
class GrVkExtensions {
public:
GrVkExtensions(uint32_t instanceExtensionCount, const char* const* instanceExtensions,
uint32_t deviceExtensionCount, const char* const* deviceExtensions);
// TODO: Remove once we remove the old fExtensions from GrVkBackendContext
GrVkExtensions(uint32_t extensionFlags);
// TODO: Remove once we remove the old fExtensions from GrVkBackendContext
static void GetExtensionArrayFromFlags(uint32_t extensionFlags,
SkTArray<const char*>* extensions);
bool hasExtension(const char[]) const;
private:
SkTArray<SkString> fExtensionStrings;
};
#endif

View File

@ -11,7 +11,6 @@
#include "SkRefCnt.h"
#include "vk/GrVkDefines.h"
#include "vk/GrVkExtensions.h"
////////////////////////////////////////////////////////////////////////////////
@ -51,25 +50,17 @@ public:
GrVkInterface(GetProc getProc,
VkInstance instance,
VkDevice device,
uint32_t instanceExtensionCount,
const char* const* instanceExtensions,
uint32_t deviceExtensionCount,
const char* const* deviceExtensions);
uint32_t extensionFlags);
// TODO: This is deprecated. Remove onces clients have switch to new interface
GrVkInterface(GetProc getProc,
GrVkInterface(const GetInstanceProc&,
const GetDeviceProc&,
VkInstance instance,
VkDevice device,
uint32_t extensionFlags);
// Validates that the GrVkInterface supports its advertised standard. This means the necessary
// function pointers have been initialized for Vulkan version.
bool validate() const;
// This is deprecated since the extensions information is stored already on the GrVkInterface.
bool validate(uint32_t /*extensionFlags*/) const {
return this->validate();
}
bool validate(uint32_t extensionFlags) const;
/**
* The function pointers are in a struct so that we can have a compiler generated assignment
@ -217,10 +208,6 @@ public:
VkPtr<PFN_vkDestroyDebugReportCallbackEXT> fDestroyDebugReportCallbackEXT;
} fFunctions;
GrVkExtensions fExtensions;
private:
void init(GetProc getProc, VkInstance instance, VkDevice device);
};
#endif

View File

@ -15,8 +15,9 @@
#include "vk/GrVkInterface.h"
GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, uint32_t featureFlags)
VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags)
: INHERITED(contextOptions) {
fCanUseGLSLForShaderModule = false;
fMustDoCopiesFromOrigin = false;
fMustSubmitCommandsBeforeCopyOp = false;
fMustSleepOnTearDown = false;
@ -47,7 +48,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
fShaderCaps.reset(new GrShaderCaps(contextOptions));
this->init(contextOptions, vkInterface, physDev, featureFlags);
this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags);
}
bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
@ -195,7 +196,7 @@ bool GrVkCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* s
}
void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice physDev, uint32_t featureFlags) {
VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) {
VkPhysicalDeviceProperties properties;
GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));

View File

@ -27,7 +27,7 @@ public:
* be called to fill out the caps.
*/
GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice device, uint32_t featureFlags);
VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
bool isConfigTexturable(GrPixelConfig config) const override {
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
@ -64,6 +64,11 @@ public:
return SkToBool(ConfigInfo::kBlitSrc_Flag & flags);
}
// Tells of if we can pass in straight GLSL string into vkCreateShaderModule
bool canUseGLSLForShaderModule() const {
return fCanUseGLSLForShaderModule;
}
// On Adreno vulkan, they do not respect the imageOffset parameter at least in
// copyImageToBuffer. This flag says that we must do the copy starting from the origin always.
bool mustDoCopiesFromOrigin() const {
@ -146,7 +151,7 @@ private:
};
void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice device, uint32_t featureFlags);
VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
void initGrCaps(const VkPhysicalDeviceProperties&,
const VkPhysicalDeviceMemoryProperties&,
uint32_t featureFlags);
@ -186,6 +191,7 @@ private:
StencilFormat fPreferedStencilFormat;
bool fCanUseGLSLForShaderModule;
bool fMustDoCopiesFromOrigin;
bool fMustSubmitCommandsBeforeCopyOp;
bool fMustSleepOnTearDown;

View File

@ -6,9 +6,7 @@
*/
#include "vk/GrVkExtensions.h"
// Can remove this once we get rid of the extension flags.
#include "vk/GrVkBackendContext.h"
#include "vk/GrVkUtil.h"
#include "SkTSearch.h"
#include "SkTSort.h"
@ -32,82 +30,232 @@ static int find_string(const SkTArray<SkString>& strings, const char ext[]) {
return idx;
}
GrVkExtensions::GrVkExtensions(uint32_t instanceExtensionCount,
const char* const* instanceExtensions,
uint32_t deviceExtensionCount,
const char* const* deviceExtensions)
: fExtensionStrings() {
#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) fGetProc("vk" #F, inst, device)
static uint32_t remove_patch_version(uint32_t specVersion) {
return (specVersion >> 12) << 12;
}
bool GrVkExtensions::initInstance(uint32_t specVersion) {
if (fGetProc == nullptr) {
return false;
}
uint32_t nonPatchVersion = remove_patch_version(specVersion);
GET_PROC_LOCAL(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
GET_PROC_LOCAL(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
for (uint32_t i = 0; i < instanceExtensionCount; ++i) {
const char* extension = instanceExtensions[i];
// if not already in the list, add it
if (find_string(fExtensionStrings, extension) < 0) {
fExtensionStrings.push_back() = extension;
SkTQSort(&fExtensionStrings.front(), &fExtensionStrings.back(), cmp);
if (!EnumerateInstanceExtensionProperties ||
!EnumerateInstanceLayerProperties) {
return false;
}
// instance layers
uint32_t layerCount = 0;
VkResult res = EnumerateInstanceLayerProperties(&layerCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkLayerProperties* layers = new VkLayerProperties[layerCount];
res = EnumerateInstanceLayerProperties(&layerCount, layers);
if (VK_SUCCESS != res) {
delete[] layers;
return false;
}
for (uint32_t i = 0; i < layerCount; ++i) {
if (nonPatchVersion <= remove_patch_version(layers[i].specVersion)) {
fInstanceLayerStrings->push_back() = layers[i].layerName;
}
}
for (uint32_t i = 0; i < deviceExtensionCount; ++i) {
const char* extension = deviceExtensions[i];
// if not already in the list, add it
if (find_string(fExtensionStrings, extension) < 0) {
fExtensionStrings.push_back() = extension;
SkTQSort(&fExtensionStrings.front(), &fExtensionStrings.back(), cmp);
}
delete[] layers;
if (!fInstanceLayerStrings->empty()) {
SkTQSort(&fInstanceLayerStrings->front(), &fInstanceLayerStrings->back(), cmp);
}
// instance extensions
// via Vulkan implementation and implicitly enabled layers
uint32_t extensionCount = 0;
res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
fInstanceExtensionStrings->push_back() = extensions[i].extensionName;
}
delete [] extensions;
// sort so we can search
if (!fInstanceExtensionStrings->empty()) {
SkTQSort(&fInstanceExtensionStrings->front(), &fInstanceExtensionStrings->back(), cmp);
}
// via explicitly enabled layers
layerCount = fInstanceLayerStrings->count();
for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
uint32_t extensionCount = 0;
res = EnumerateInstanceExtensionProperties((*fInstanceLayerStrings)[layerIndex].c_str(),
&extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateInstanceExtensionProperties((*fInstanceLayerStrings)[layerIndex].c_str(),
&extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
// if not already in the list, add it
if (find_string(*fInstanceExtensionStrings, extensions[i].extensionName) < 0) {
fInstanceExtensionStrings->push_back() = extensions[i].extensionName;
SkTQSort(&fInstanceExtensionStrings->front(), &fInstanceExtensionStrings->back(),
cmp);
}
}
delete[] extensions;
}
return true;
}
GrVkExtensions::GrVkExtensions(uint32_t extensionFlags)
: fExtensionStrings() {
bool GrVkExtensions::initDevice(uint32_t specVersion, VkInstance inst, VkPhysicalDevice physDev) {
if (fGetProc == nullptr) {
return false;
}
uint32_t nonPatchVersion = remove_patch_version(specVersion);
GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst, VK_NULL_HANDLE);
GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst, VK_NULL_HANDLE);
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
SkTArray<const char*> extensionNames;
GetExtensionArrayFromFlags(extensionFlags, &extensionNames);
for (int i = 0; i < extensionNames.count(); ++i) {
// if not already in the list, add it
if (find_string(fExtensionStrings, extensionNames[i]) < 0) {
fExtensionStrings.push_back() = extensionNames[i];
SkTQSort(&fExtensionStrings.front(), &fExtensionStrings.back(), cmp);
if (!EnumerateDeviceExtensionProperties ||
!EnumerateDeviceLayerProperties) {
return false;
}
// device layers
uint32_t layerCount = 0;
VkResult res = EnumerateDeviceLayerProperties(physDev, &layerCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkLayerProperties* layers = new VkLayerProperties[layerCount];
res = EnumerateDeviceLayerProperties(physDev, &layerCount, layers);
if (VK_SUCCESS != res) {
delete[] layers;
return false;
}
for (uint32_t i = 0; i < layerCount; ++i) {
if (nonPatchVersion <= remove_patch_version(layers[i].specVersion)) {
fDeviceLayerStrings->push_back() = layers[i].layerName;
}
}
delete[] layers;
if (!fDeviceLayerStrings->empty()) {
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
SkTQSort(&fDeviceLayerStrings->front(), &fDeviceLayerStrings->back(), cmp);
}
// device extensions
// via Vulkan implementation and implicitly enabled layers
uint32_t extensionCount = 0;
res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
fDeviceExtensionStrings->push_back() = extensions[i].extensionName;
}
delete[] extensions;
if (!fDeviceExtensionStrings->empty()) {
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
SkTQSort(&fDeviceExtensionStrings->front(), &fDeviceExtensionStrings->back(), cmp);
}
// via explicitly enabled layers
layerCount = fDeviceLayerStrings->count();
for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
uint32_t extensionCount = 0;
res = EnumerateDeviceExtensionProperties(physDev,
(*fDeviceLayerStrings)[layerIndex].c_str(),
&extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateDeviceExtensionProperties(physDev,
(*fDeviceLayerStrings)[layerIndex].c_str(),
&extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
// if not already in the list, add it
if (find_string(*fDeviceExtensionStrings, extensions[i].extensionName) < 0) {
fDeviceExtensionStrings->push_back() = extensions[i].extensionName;
SkTQSort(&fDeviceExtensionStrings->front(), &fDeviceExtensionStrings->back(), cmp);
}
}
delete[] extensions;
}
return true;
}
bool GrVkExtensions::hasExtension(const char ext[]) const {
return find_string(fExtensionStrings, ext) >= 0;
bool GrVkExtensions::hasInstanceExtension(const char ext[]) const {
return find_string(*fInstanceExtensionStrings, ext) >= 0;
}
void GrVkExtensions::GetExtensionArrayFromFlags(uint32_t extensionFlags,
SkTArray<const char*>* extensions) {
#ifdef SK_ENABLE_VK_LAYERS
if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
extensions->push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
}
#endif
if (extensionFlags & kKHR_surface_GrVkExtensionFlag) {
extensions->push_back(VK_KHR_SURFACE_EXTENSION_NAME);
}
if (extensionFlags & kKHR_swapchain_GrVkExtensionFlag) {
extensions->push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
}
#ifdef SK_BUILD_FOR_WIN
if (extensionFlags & kKHR_win32_surface_GrVkExtensionFlag) {
extensions->push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
}
#elif defined(SK_BUILD_FOR_ANDROID)
if (extensionFlags & kKHR_android_surface_GrVkExtensionFlag) {
extensions->push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
}
#elif defined(SK_BUILD_FOR_UNIX) && !defined(__Fuchsia__)
if (extensionFlags & kKHR_xcb_surface_GrVkExtensionFlag) {
extensions->push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
}
#endif
// Device extensions
if (extensionFlags & kKHR_swapchain_GrVkExtensionFlag) {
extensions->push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
}
if (extensionFlags & kNV_glsl_shader_GrVkExtensionFlag) {
extensions->push_back("VK_NV_glsl_shader");
}
bool GrVkExtensions::hasDeviceExtension(const char ext[]) const {
return find_string(*fDeviceExtensionStrings, ext) >= 0;
}
bool GrVkExtensions::hasInstanceLayer(const char ext[]) const {
return find_string(*fInstanceLayerStrings, ext) >= 0;
}
bool GrVkExtensions::hasDeviceLayer(const char ext[]) const {
return find_string(*fDeviceLayerStrings, ext) >= 0;
}
void GrVkExtensions::print(const char* sep) const {
if (nullptr == sep) {
sep = " ";
}
int cnt = fInstanceExtensionStrings->count();
SkDebugf("Instance Extensions: ");
for (int i = 0; i < cnt; ++i) {
SkDebugf("%s%s", (*fInstanceExtensionStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
}
cnt = fDeviceExtensionStrings->count();
SkDebugf("\nDevice Extensions: ");
for (int i = 0; i < cnt; ++i) {
SkDebugf("%s%s", (*fDeviceExtensionStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
}
cnt = fInstanceLayerStrings->count();
SkDebugf("\nInstance Layers: ");
for (int i = 0; i < cnt; ++i) {
SkDebugf("%s%s", (*fInstanceLayerStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
}
cnt = fDeviceLayerStrings->count();
SkDebugf("\nDevice Layers: ");
for (int i = 0; i < cnt; ++i) {
SkDebugf("%s%s", (*fDeviceLayerStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrVkExtensions_DEFINED
#define GrVkExtensions_DEFINED
#include "../private/SkTArray.h"
#include "SkString.h"
#include "vk/GrVkDefines.h"
#include "vk/GrVkInterface.h"
/**
* This helper queries the Vulkan driver for available extensions and layers, remembers them,
* and can be queried. It supports queries for both instance and device extensions and layers.
*/
class SK_API GrVkExtensions {
public:
GrVkExtensions(GrVkInterface::GetProc getProc)
: fGetProc(getProc)
, fInstanceExtensionStrings(new SkTArray<SkString>)
, fDeviceExtensionStrings(new SkTArray<SkString>)
, fInstanceLayerStrings(new SkTArray<SkString>)
, fDeviceLayerStrings(new SkTArray<SkString>) {}
bool initInstance(uint32_t specVersion);
bool initDevice(uint32_t specVersion, VkInstance, VkPhysicalDevice);
/**
* Queries whether an extension or layer is present. Will fail if not initialized.
*/
bool hasInstanceExtension(const char[]) const;
bool hasDeviceExtension(const char[]) const;
bool hasInstanceLayer(const char[]) const;
bool hasDeviceLayer(const char[]) const;
void print(const char* sep = "\n") const;
private:
GrVkInterface::GetProc fGetProc;
std::unique_ptr<SkTArray<SkString>> fInstanceExtensionStrings;
std::unique_ptr<SkTArray<SkString>> fDeviceExtensionStrings;
std::unique_ptr<SkTArray<SkString>> fInstanceLayerStrings;
std::unique_ptr<SkTArray<SkString>> fDeviceLayerStrings;
};
#endif

View File

@ -36,7 +36,6 @@
#include "SkMipMap.h"
#include "SkSLCompiler.h"
#include "SkTo.h"
#include "vk/GrVkInterface.h"
#include "vk/GrVkTypes.h"
@ -59,7 +58,7 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
return nullptr;
}
if (!backendContext.fInterface ||
!backendContext.fInterface->validate()) {
!backendContext.fInterface->validate(backendContext.fExtensions)) {
return nullptr;
}
@ -89,7 +88,7 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
fCompiler = new SkSL::Compiler();
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
backendContext.fFeatures));
backendContext.fFeatures, backendContext.fExtensions));
fCaps.reset(SkRef(fVkCaps.get()));
VK_CALL(GetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &fPhysDevProps));

View File

@ -144,7 +144,7 @@ public:
bool updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size);
private:
GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext&);
GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext& backendContext);
void onResetContext(uint32_t resetBits) override {}

View File

@ -22,27 +22,20 @@ GrVkInterface::GetProc make_unified_getter(const GrVkInterface::GetInstanceProc&
};
}
GrVkInterface::GrVkInterface(GetProc getProc,
GrVkInterface::GrVkInterface(const GetInstanceProc& getInstanceProc,
const GetDeviceProc& getDeviceProc,
VkInstance instance,
VkDevice device,
uint32_t extensionFlags)
: fExtensions(extensionFlags) {
this->init(getProc, instance, device);
}
: GrVkInterface(make_unified_getter(getInstanceProc, getDeviceProc),
instance,
device,
extensionFlags) {}
GrVkInterface::GrVkInterface(GetProc getProc,
VkInstance instance,
VkDevice device,
uint32_t instanceExtensionCount,
const char* const* instanceExtensions,
uint32_t deviceExtensionCount,
const char* const* deviceExtensions)
: fExtensions(instanceExtensionCount, instanceExtensions, deviceExtensionCount,
deviceExtensions) {
this->init(getProc, instance, device);
}
void GrVkInterface::init(GetProc getProc, VkInstance instance, VkDevice device) {
uint32_t extensionFlags) {
if (getProc == nullptr) {
return;
}
@ -66,7 +59,7 @@ void GrVkInterface::init(GetProc getProc, VkInstance instance, VkDevice device)
ACQUIRE_PROC(EnumerateDeviceExtensionProperties, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(EnumerateDeviceLayerProperties, instance, VK_NULL_HANDLE);
if (fExtensions.hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
// Also instance Procs.
ACQUIRE_PROC(CreateDebugReportCallbackEXT, instance, VK_NULL_HANDLE);
ACQUIRE_PROC(DebugReportMessageEXT, instance, VK_NULL_HANDLE);
@ -205,7 +198,7 @@ void GrVkInterface::init(GetProc getProc, VkInstance instance, VkDevice device)
if (kIsDebug) { SkDebugf("%s:%d GrVkInterface::validate() failed.\n", __FILE__, __LINE__); } \
return false;
bool GrVkInterface::validate() const {
bool GrVkInterface::validate(uint32_t extensionFlags) const {
// functions that are always required
if (nullptr == fFunctions.fCreateInstance ||
nullptr == fFunctions.fDestroyInstance ||
@ -345,7 +338,7 @@ bool GrVkInterface::validate() const {
RETURN_FALSE_INTERFACE
}
if (fExtensions.hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
if (nullptr == fFunctions.fCreateDebugReportCallbackEXT ||
nullptr == fFunctions.fDebugReportMessageEXT ||
nullptr == fFunctions.fDestroyDebugReportCallbackEXT) {

View File

@ -59,22 +59,36 @@ const char* kDebugLayerNames[] = {
"VK_LAYER_GOOGLE_threading",
"VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_object_tracker",
"VK_LAYER_LUNARG_image",
"VK_LAYER_LUNARG_core_validation",
"VK_LAYER_LUNARG_swapchain",
"VK_LAYER_GOOGLE_unique_objects",
// not included in standard_validation
//"VK_LAYER_LUNARG_api_dump",
//"VK_LAYER_LUNARG_vktrace",
//"VK_LAYER_LUNARG_screenshot",
};
#endif
static bool should_include_debug_layer(const VkLayerProperties& layerProps) {
for (size_t i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) {
if (!strcmp(layerProps.layerName, kDebugLayerNames[i])) {
return true;
}
// the minimum version of Vulkan supported
#ifdef SK_BUILD_FOR_ANDROID
const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3);
#else
const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 8);
#endif
#define ACQUIRE_VK_PROC(name, instance, device) \
PFN_vk##name grVk##name = \
reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
if (grVk##name == nullptr) { \
SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
if (device != VK_NULL_HANDLE) { \
destroy_instance(getProc, inst, debugCallback, hasDebugExtension); \
} \
return false; \
}
return false;
}
#ifdef SK_ENABLE_VK_LAYERS
VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
@ -98,202 +112,6 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
}
#endif
#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, device)
#ifdef SK_ENABLE_VK_LAYERS
static uint32_t remove_patch_version(uint32_t specVersion) {
return (specVersion >> 12) << 12;
}
#endif
static bool init_instance_extensions_and_layers(GrVkInterface::GetProc getProc,
uint32_t specVersion,
SkTArray<VkExtensionProperties>* instanceExtensions,
SkTArray<VkLayerProperties>* instanceLayers) {
if (getProc == nullptr) {
return false;
}
GET_PROC_LOCAL(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
GET_PROC_LOCAL(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
if (!EnumerateInstanceExtensionProperties ||
!EnumerateInstanceLayerProperties) {
return false;
}
VkResult res;
uint32_t layerCount = 0;
#ifdef SK_ENABLE_VK_LAYERS
// instance layers
res = EnumerateInstanceLayerProperties(&layerCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkLayerProperties* layers = new VkLayerProperties[layerCount];
res = EnumerateInstanceLayerProperties(&layerCount, layers);
if (VK_SUCCESS != res) {
delete[] layers;
return false;
}
uint32_t nonPatchVersion = remove_patch_version(specVersion);
for (uint32_t i = 0; i < layerCount; ++i) {
if (nonPatchVersion <= remove_patch_version(layers[i].specVersion) &&
should_include_debug_layer(layers[i])) {
instanceLayers->push_back() = layers[i];
}
}
delete[] layers;
#endif
// instance extensions
// via Vulkan implementation and implicitly enabled layers
uint32_t extensionCount = 0;
res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
instanceExtensions->push_back() = extensions[i];
}
delete [] extensions;
// via explicitly enabled layers
layerCount = instanceLayers->count();
for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
uint32_t extensionCount = 0;
res = EnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
&extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
&extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
instanceExtensions->push_back() = extensions[i];
}
delete[] extensions;
}
return true;
}
static bool init_device_extensions_and_layers(GrVkInterface::GetProc getProc, uint32_t specVersion,
VkInstance inst, VkPhysicalDevice physDev,
SkTArray<VkExtensionProperties>* deviceExtensions,
SkTArray<VkLayerProperties>* deviceLayers) {
if (getProc == nullptr) {
return false;
}
GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst, VK_NULL_HANDLE);
GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst, VK_NULL_HANDLE);
if (!EnumerateDeviceExtensionProperties ||
!EnumerateDeviceLayerProperties) {
return false;
}
VkResult res;
// device layers
uint32_t layerCount = 0;
#ifdef SK_ENABLE_VK_LAYERS
res = EnumerateDeviceLayerProperties(physDev, &layerCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkLayerProperties* layers = new VkLayerProperties[layerCount];
res = EnumerateDeviceLayerProperties(physDev, &layerCount, layers);
if (VK_SUCCESS != res) {
delete[] layers;
return false;
}
uint32_t nonPatchVersion = remove_patch_version(specVersion);
for (uint32_t i = 0; i < layerCount; ++i) {
if (nonPatchVersion <= remove_patch_version(layers[i].specVersion) &&
should_include_debug_layer(layers[i])) {
deviceLayers->push_back() = layers[i];
}
}
delete[] layers;
#endif
// device extensions
// via Vulkan implementation and implicitly enabled layers
uint32_t extensionCount = 0;
res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
deviceExtensions->push_back() = extensions[i];
}
delete[] extensions;
// via explicitly enabled layers
layerCount = deviceLayers->count();
for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
uint32_t extensionCount = 0;
res = EnumerateDeviceExtensionProperties(physDev,
(*deviceLayers)[layerIndex].layerName,
&extensionCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
res = EnumerateDeviceExtensionProperties(physDev,
(*deviceLayers)[layerIndex].layerName,
&extensionCount, extensions);
if (VK_SUCCESS != res) {
delete[] extensions;
return false;
}
for (uint32_t i = 0; i < extensionCount; ++i) {
deviceExtensions->push_back() = extensions[i];
}
delete[] extensions;
}
return true;
}
// the minimum version of Vulkan supported
#ifdef SK_BUILD_FOR_ANDROID
const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3);
#else
const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 8);
#endif
#define ACQUIRE_VK_PROC(name, instance, device) \
PFN_vk##name grVk##name = \
reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
if (grVk##name == nullptr) { \
SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
if (device != VK_NULL_HANDLE) { \
destroy_instance(getProc, inst, debugCallback, hasDebugExtension); \
} \
return false; \
}
#define ACQUIRE_VK_PROC_LOCAL(name, instance, device) \
PFN_vk##name grVk##name = \
reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
@ -343,25 +161,50 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
kGrVkMinimumVersion, // apiVersion
};
SkTArray<VkLayerProperties> instanceLayers;
SkTArray<VkExtensionProperties> instanceExtensions;
if (!init_instance_extensions_and_layers(getProc, kGrVkMinimumVersion,
&instanceExtensions,
&instanceLayers)) {
return false;
}
GrVkExtensions extensions(getProc);
extensions.initInstance(kGrVkMinimumVersion);
SkTArray<const char*> instanceLayerNames;
SkTArray<const char*> instanceExtensionNames;
for (int i = 0; i < instanceLayers.count(); ++i) {
instanceLayerNames.push_back(instanceLayers[i].layerName);
}
for (int i = 0; i < instanceExtensions.count(); ++i) {
if (strncmp(instanceExtensions[i].extensionName, "VK_KHX", 6)) {
instanceExtensionNames.push_back(instanceExtensions[i].extensionName);
uint32_t extensionFlags = 0;
bool hasDebugExtension = false;
#ifdef SK_ENABLE_VK_LAYERS
for (size_t i = 0; i < SK_ARRAY_COUNT(kDebugLayerNames); ++i) {
if (extensions.hasInstanceLayer(kDebugLayerNames[i])) {
instanceLayerNames.push_back(kDebugLayerNames[i]);
}
}
if (extensions.hasInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
instanceExtensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
extensionFlags |= kEXT_debug_report_GrVkExtensionFlag;
hasDebugExtension = true;
}
#endif
if (extensions.hasInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME)) {
instanceExtensionNames.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
extensionFlags |= kKHR_surface_GrVkExtensionFlag;
}
if (extensions.hasInstanceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
instanceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
extensionFlags |= kKHR_swapchain_GrVkExtensionFlag;
}
#ifdef SK_BUILD_FOR_WIN
if (extensions.hasInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME)) {
instanceExtensionNames.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
extensionFlags |= kKHR_win32_surface_GrVkExtensionFlag;
}
#elif defined(SK_BUILD_FOR_ANDROID)
if (extensions.hasInstanceExtension(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)) {
instanceExtensionNames.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
extensionFlags |= kKHR_android_surface_GrVkExtensionFlag;
}
#elif defined(SK_BUILD_FOR_UNIX) && !defined(__Fuchsia__)
if (extensions.hasInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) {
instanceExtensionNames.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
extensionFlags |= kKHR_xcb_surface_GrVkExtensionFlag;
}
#endif
const VkInstanceCreateInfo instance_create = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
@ -374,8 +217,6 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
instanceExtensionNames.begin(), // ppEnabledExtensionNames
};
bool hasDebugExtension = false;
ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE);
err = grVkCreateInstance(&instance_create, nullptr, &inst);
if (err < 0) {
@ -409,6 +250,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
}
#endif
ACQUIRE_VK_PROC(DestroyInstance, inst, VK_NULL_HANDLE);
ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst, VK_NULL_HANDLE);
ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst, VK_NULL_HANDLE);
ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst, VK_NULL_HANDLE);
@ -490,29 +332,17 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
presentQueueIndex = graphicsQueueIndex;
}
SkTArray<VkLayerProperties> deviceLayers;
SkTArray<VkExtensionProperties> deviceExtensions;
if (!init_device_extensions_and_layers(getProc, kGrVkMinimumVersion,
inst, physDev,
&deviceExtensions,
&deviceLayers)) {
destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
return false;
}
extensions.initDevice(kGrVkMinimumVersion, inst, physDev);
SkTArray<const char*> deviceLayerNames;
SkTArray<const char*> deviceExtensionNames;
for (int i = 0; i < deviceLayers.count(); ++i) {
deviceLayerNames.push_back(deviceLayers[i].layerName);
if (extensions.hasDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
deviceExtensionNames.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
extensionFlags |= kKHR_swapchain_GrVkExtensionFlag;
}
for (int i = 0; i < deviceExtensions.count(); ++i) {
// Don't use experimental extensions since they typically don't work with debug layers and
// often are missing dependecy requirements for other extensions. Additionally, these are
// often left behind in the driver even after they've been promoted to real extensions.
if (strncmp(deviceExtensions[i].extensionName, "VK_KHX", 6) &&
strncmp(deviceExtensions[i].extensionName, "VK_NVX", 6)) {
deviceExtensionNames.push_back(deviceExtensions[i].extensionName);
}
if (extensions.hasDeviceExtension("VK_NV_glsl_shader")) {
deviceExtensionNames.push_back("VK_NV_glsl_shader");
extensionFlags |= kNV_glsl_shader_GrVkExtensionFlag;
}
// query to get the physical device properties
@ -576,13 +406,9 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
return false;
}
auto interface = sk_make_sp<GrVkInterface>(getProc, inst, device,
(uint32_t) instanceExtensionNames.count(),
instanceExtensionNames.begin(),
(uint32_t) deviceExtensionNames.count(),
deviceExtensionNames.begin());
if (!interface->validate()) {
auto interface =
sk_make_sp<GrVkInterface>(getProc, inst, device, extensionFlags);
if (!interface->validate(extensionFlags)) {
SkDebugf("Vulkan interface validation failed\n");
grVkDeviceWaitIdle(device);
grVkDestroyDevice(device, nullptr);
@ -599,7 +425,7 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro
ctx->fQueue = queue;
ctx->fGraphicsQueueIndex = graphicsQueueIndex;
ctx->fMinAPIVersion = kGrVkMinimumVersion;
ctx->fExtensions = 0;
ctx->fExtensions = extensionFlags;
ctx->fFeatures = featureFlags;
ctx->fInterface.reset(interface.release());
ctx->fOwnsInstanceAndDevice = false;

View File

@ -12,7 +12,6 @@
#include "SkSurface.h"
#include "VulkanWindowContext.h"
#include "vk/GrVkExtensions.h"
#include "vk/GrVkImage.h"
#include "vk/GrVkUtil.h"
#include "vk/GrVkTypes.h"
@ -57,8 +56,8 @@ void VulkanWindowContext::initializeContext() {
return;
}
if (!backendContext.fInterface->fExtensions.hasExtension(VK_KHR_SURFACE_EXTENSION_NAME) ||
!backendContext.fInterface->fExtensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
if (!(backendContext.fExtensions & kKHR_surface_GrVkExtensionFlag) ||
!(backendContext.fExtensions & kKHR_swapchain_GrVkExtensionFlag)) {
return;
}