Reland "Reland "Let client pass in full extension to GrVkBackendContext.""
This reverts commitdc13c21b1e
. Reason for revert: fuchsia should be fixed Original change's description: > Revert "Reland "Let client pass in full extension to GrVkBackendContext."" > > This reverts commita782dcb3c4
. > > Reason for revert: fuchsia changes reverted > > Original change's description: > > Reland "Let client pass in full extension to GrVkBackendContext." > > > > This reverts commitcb92b26e5c
. > > > > Reason for revert: <INSERT REASONING HERE> > > > > Original change's description: > > > Revert "Let client pass in full extension to GrVkBackendContext." > > > > > > This reverts commit45c9dab4c3
. > > > > > > 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> 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: Ied1323b7197b600e895d85ac7e85d6f65985dabc Reviewed-on: https://skia-review.googlesource.com/139002 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
def554697b
commit
98bffae9c1
@ -535,6 +535,7 @@ 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/GrVkMemoryAllocator.h",
|
||||
"$_include/gpu/vk/GrVkTypes.h",
|
||||
"$_include/private/GrVkTypesPriv.h",
|
||||
@ -559,7 +560,6 @@ 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",
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "SkRefCnt.h"
|
||||
#include "vk/GrVkMemoryAllocator.h"
|
||||
|
||||
class GrVkExtensions;
|
||||
|
||||
enum GrVkExtensionFlags {
|
||||
kEXT_debug_report_GrVkExtensionFlag = 0x0001,
|
||||
kNV_glsl_shader_GrVkExtensionFlag = 0x0002,
|
||||
@ -50,11 +52,11 @@ struct SK_API GrVkBackendContext {
|
||||
VkQueue fQueue;
|
||||
uint32_t fGraphicsQueueIndex;
|
||||
uint32_t fMinAPIVersion;
|
||||
uint32_t fExtensions;
|
||||
uint32_t fFeatures;
|
||||
uint32_t fExtensions = 0;
|
||||
const GrVkExtensions* fVkExtensions = nullptr;
|
||||
uint32_t fFeatures = 0;
|
||||
sk_sp<GrVkMemoryAllocator> fMemoryAllocator;
|
||||
GrVkGetProc fGetProc = nullptr;
|
||||
|
||||
// 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;
|
||||
|
31
include/gpu/vk/GrVkExtensions.h
Normal file
31
include/gpu/vk/GrVkExtensions.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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() {}
|
||||
|
||||
void init(uint32_t instanceExtensionCount, const char* const* instanceExtensions,
|
||||
uint32_t deviceExtensionCount, const char* const* deviceExtensions);
|
||||
|
||||
bool hasExtension(const char[]) const;
|
||||
|
||||
private:
|
||||
SkTArray<SkString> fExtensionStrings;
|
||||
};
|
||||
|
||||
#endif
|
@ -15,9 +15,8 @@
|
||||
#include "vk/GrVkBackendContext.h"
|
||||
|
||||
GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
|
||||
VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags)
|
||||
VkPhysicalDevice physDev, uint32_t featureFlags)
|
||||
: INHERITED(contextOptions) {
|
||||
fCanUseGLSLForShaderModule = false;
|
||||
fMustDoCopiesFromOrigin = false;
|
||||
fMustSubmitCommandsBeforeCopyOp = false;
|
||||
fMustSleepOnTearDown = false;
|
||||
@ -48,7 +47,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
|
||||
|
||||
fShaderCaps.reset(new GrShaderCaps(contextOptions));
|
||||
|
||||
this->init(contextOptions, vkInterface, physDev, featureFlags, extensionFlags);
|
||||
this->init(contextOptions, vkInterface, physDev, featureFlags);
|
||||
}
|
||||
|
||||
bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
|
||||
@ -196,7 +195,7 @@ bool GrVkCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* s
|
||||
}
|
||||
|
||||
void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
|
||||
VkPhysicalDevice physDev, uint32_t featureFlags, uint32_t extensionFlags) {
|
||||
VkPhysicalDevice physDev, uint32_t featureFlags) {
|
||||
|
||||
VkPhysicalDeviceProperties properties;
|
||||
GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
* be called to fill out the caps.
|
||||
*/
|
||||
GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
|
||||
VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
|
||||
VkPhysicalDevice device, uint32_t featureFlags);
|
||||
|
||||
bool isConfigTexturable(GrPixelConfig config) const override {
|
||||
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
|
||||
@ -64,11 +64,6 @@ 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 {
|
||||
@ -151,7 +146,7 @@ private:
|
||||
};
|
||||
|
||||
void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
|
||||
VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
|
||||
VkPhysicalDevice device, uint32_t featureFlags);
|
||||
void initGrCaps(const VkPhysicalDeviceProperties&,
|
||||
const VkPhysicalDeviceMemoryProperties&,
|
||||
uint32_t featureFlags);
|
||||
@ -191,7 +186,6 @@ private:
|
||||
|
||||
StencilFormat fPreferedStencilFormat;
|
||||
|
||||
bool fCanUseGLSLForShaderModule;
|
||||
bool fMustDoCopiesFromOrigin;
|
||||
bool fMustSubmitCommandsBeforeCopyOp;
|
||||
bool fMustSleepOnTearDown;
|
||||
|
@ -6,7 +6,9 @@
|
||||
*/
|
||||
|
||||
#include "vk/GrVkExtensions.h"
|
||||
#include "vk/GrVkUtil.h"
|
||||
|
||||
// Can remove this once we get rid of the extension flags.
|
||||
#include "vk/GrVkBackendContext.h"
|
||||
|
||||
#include "SkTSearch.h"
|
||||
#include "SkTSort.h"
|
||||
@ -30,232 +32,31 @@ static int find_string(const SkTArray<SkString>& strings, const char ext[]) {
|
||||
return idx;
|
||||
}
|
||||
|
||||
#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);
|
||||
|
||||
void GrVkExtensions::init(uint32_t instanceExtensionCount,
|
||||
const char* const* instanceExtensions,
|
||||
uint32_t deviceExtensionCount,
|
||||
const char* const* deviceExtensions) {
|
||||
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> 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 < 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 : "");
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +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 "GrVkInterface.h"
|
||||
#include "SkString.h"
|
||||
#include "vk/GrVkTypes.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(GrVkGetProc 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:
|
||||
GrVkGetProc 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
|
@ -36,6 +36,7 @@
|
||||
#include "SkMipMap.h"
|
||||
#include "SkSLCompiler.h"
|
||||
#include "SkTo.h"
|
||||
|
||||
#include "vk/GrVkTypes.h"
|
||||
|
||||
#include <utility>
|
||||
@ -64,13 +65,27 @@ sk_sp<GrGpu> GrVkGpu::Make(const GrVkBackendContext& backendContext,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<const GrVkInterface> interface(new GrVkInterface(backendContext.fGetProc,
|
||||
backendContext.fInstance,
|
||||
backendContext.fDevice,
|
||||
backendContext.fExtensions));
|
||||
sk_sp<const GrVkInterface> interface;
|
||||
|
||||
if (!interface->validate(backendContext.fExtensions)) {
|
||||
return nullptr;
|
||||
if (backendContext.fVkExtensions) {
|
||||
interface.reset(new GrVkInterface(backendContext.fGetProc,
|
||||
backendContext.fInstance,
|
||||
backendContext.fDevice,
|
||||
backendContext.fVkExtensions));
|
||||
if (!interface->validate(backendContext.fVkExtensions)) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// None of our current GrVkExtension flags actually affect the vulkan backend so we just
|
||||
// make an empty GrVkExtensions and pass that to the GrVkInterface.
|
||||
GrVkExtensions extensions;
|
||||
interface.reset(new GrVkInterface(backendContext.fGetProc,
|
||||
backendContext.fInstance,
|
||||
backendContext.fDevice,
|
||||
&extensions));
|
||||
if (!interface->validate(&extensions)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return sk_sp<GrGpu>(new GrVkGpu(context, options, backendContext, interface));
|
||||
@ -99,7 +114,7 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
|
||||
fCompiler = new SkSL::Compiler();
|
||||
|
||||
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendContext.fPhysicalDevice,
|
||||
backendContext.fFeatures, backendContext.fExtensions));
|
||||
backendContext.fFeatures));
|
||||
fCaps.reset(SkRef(fVkCaps.get()));
|
||||
|
||||
VK_CALL(GetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &fPhysDevProps));
|
||||
|
@ -144,7 +144,7 @@ public:
|
||||
bool updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size);
|
||||
|
||||
private:
|
||||
GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext& backendContext,
|
||||
GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext&,
|
||||
sk_sp<const GrVkInterface>);
|
||||
|
||||
void onResetContext(uint32_t resetBits) override {}
|
||||
|
@ -15,7 +15,7 @@
|
||||
GrVkInterface::GrVkInterface(GrVkGetProc getProc,
|
||||
VkInstance instance,
|
||||
VkDevice device,
|
||||
uint32_t extensionFlags) {
|
||||
const GrVkExtensions* extensions) {
|
||||
if (getProc == nullptr) {
|
||||
return;
|
||||
}
|
||||
@ -39,7 +39,7 @@ GrVkInterface::GrVkInterface(GrVkGetProc getProc,
|
||||
ACQUIRE_PROC(EnumerateDeviceExtensionProperties, instance, VK_NULL_HANDLE);
|
||||
ACQUIRE_PROC(EnumerateDeviceLayerProperties, instance, VK_NULL_HANDLE);
|
||||
|
||||
if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
|
||||
if (extensions->hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
|
||||
// Also instance Procs.
|
||||
ACQUIRE_PROC(CreateDebugReportCallbackEXT, instance, VK_NULL_HANDLE);
|
||||
ACQUIRE_PROC(DebugReportMessageEXT, instance, VK_NULL_HANDLE);
|
||||
@ -178,7 +178,7 @@ GrVkInterface::GrVkInterface(GrVkGetProc getProc,
|
||||
if (kIsDebug) { SkDebugf("%s:%d GrVkInterface::validate() failed.\n", __FILE__, __LINE__); } \
|
||||
return false;
|
||||
|
||||
bool GrVkInterface::validate(uint32_t extensionFlags) const {
|
||||
bool GrVkInterface::validate(const GrVkExtensions* extensions) const {
|
||||
// functions that are always required
|
||||
if (nullptr == fFunctions.fCreateInstance ||
|
||||
nullptr == fFunctions.fDestroyInstance ||
|
||||
@ -318,7 +318,7 @@ bool GrVkInterface::validate(uint32_t extensionFlags) const {
|
||||
RETURN_FALSE_INTERFACE
|
||||
}
|
||||
|
||||
if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) {
|
||||
if (extensions->hasExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
|
||||
if (nullptr == fFunctions.fCreateDebugReportCallbackEXT ||
|
||||
nullptr == fFunctions.fDebugReportMessageEXT ||
|
||||
nullptr == fFunctions.fDestroyDebugReportCallbackEXT) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "vk/GrVkBackendContext.h"
|
||||
#include "vk/GrVkTypes.h"
|
||||
#include "vk/GrVkExtensions.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -39,11 +40,11 @@ public:
|
||||
GrVkInterface(GrVkGetProc getProc,
|
||||
VkInstance instance,
|
||||
VkDevice device,
|
||||
uint32_t extensionFlags);
|
||||
const GrVkExtensions*);
|
||||
|
||||
// Validates that the GrVkInterface supports its advertised standard. This means the necessary
|
||||
// function pointers have been initialized for Vulkan version.
|
||||
bool validate(uint32_t extensionFlags) const;
|
||||
bool validate(const GrVkExtensions*) const;
|
||||
|
||||
/**
|
||||
* The function pointers are in a struct so that we can have a compiler generated assignment
|
||||
@ -190,7 +191,6 @@ public:
|
||||
VkPtr<PFN_vkDebugReportMessageEXT> fDebugReportMessageEXT;
|
||||
VkPtr<PFN_vkDestroyDebugReportCallbackEXT> fDestroyDebugReportCallbackEXT;
|
||||
} fFunctions;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "GrContext.h"
|
||||
#include "VkTestUtils.h"
|
||||
#include "vk/GrVkExtensions.h"
|
||||
#include "vk/GrVkInterface.h"
|
||||
#include "vk/GrVkUtil.h"
|
||||
|
||||
@ -149,10 +150,12 @@ class VkTestContextImpl : public sk_gpu_test::VkTestContext {
|
||||
public:
|
||||
static VkTestContext* Create(VkTestContext* sharedContext) {
|
||||
GrVkBackendContext backendContext;
|
||||
GrVkExtensions* extensions;
|
||||
bool ownsContext = true;
|
||||
VkDebugReportCallbackEXT debugCallback = VK_NULL_HANDLE;
|
||||
if (sharedContext) {
|
||||
backendContext = sharedContext->getVkBackendContext();
|
||||
extensions = const_cast<GrVkExtensions*>(sharedContext->getVkExtensions());
|
||||
// We always delete the parent context last so make sure the child does not think they
|
||||
// own the vulkan context.
|
||||
ownsContext = false;
|
||||
@ -169,12 +172,13 @@ public:
|
||||
}
|
||||
return instProc(instance, proc_name);
|
||||
};
|
||||
if (!sk_gpu_test::CreateVkBackendContext(getProc, &backendContext,
|
||||
extensions = new GrVkExtensions();
|
||||
if (!sk_gpu_test::CreateVkBackendContext(getProc, &backendContext, extensions,
|
||||
&debugCallback)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return new VkTestContextImpl(backendContext, ownsContext, debugCallback);
|
||||
return new VkTestContextImpl(backendContext, extensions, ownsContext, debugCallback);
|
||||
}
|
||||
|
||||
~VkTestContextImpl() override { this->teardown(); }
|
||||
@ -215,13 +219,14 @@ protected:
|
||||
}
|
||||
#endif
|
||||
grVkDestroyInstance(fVk.fInstance, nullptr);
|
||||
delete fExtensions;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
VkTestContextImpl(const GrVkBackendContext& backendContext, bool ownsContext,
|
||||
VkDebugReportCallbackEXT debugCallback)
|
||||
: VkTestContext(backendContext, ownsContext, debugCallback) {
|
||||
VkTestContextImpl(const GrVkBackendContext& backendContext, const GrVkExtensions* extensions,
|
||||
bool ownsContext, VkDebugReportCallbackEXT debugCallback)
|
||||
: VkTestContext(backendContext, extensions, ownsContext, debugCallback) {
|
||||
fFenceSync.reset(new VkFenceSync(fVk.fGetProc, fVk.fDevice, fVk.fQueue,
|
||||
fVk.fGraphicsQueueIndex));
|
||||
}
|
||||
|
@ -15,22 +15,32 @@
|
||||
#include "GrVulkanDefines.h"
|
||||
#include "vk/GrVkBackendContext.h"
|
||||
|
||||
class GrVkExtensions;
|
||||
|
||||
namespace sk_gpu_test {
|
||||
class VkTestContext : public TestContext {
|
||||
public:
|
||||
virtual GrBackend backend() override { return kVulkan_GrBackend; }
|
||||
|
||||
const GrVkBackendContext& getVkBackendContext() {
|
||||
const GrVkBackendContext& getVkBackendContext() const {
|
||||
return fVk;
|
||||
}
|
||||
|
||||
protected:
|
||||
VkTestContext(const GrVkBackendContext& vk, bool ownsContext,
|
||||
VkDebugReportCallbackEXT debugCallback)
|
||||
: fVk(vk), fOwnsContext(ownsContext), fDebugCallback(debugCallback) {}
|
||||
const GrVkExtensions* getVkExtensions() const {
|
||||
return fExtensions;
|
||||
}
|
||||
|
||||
GrVkBackendContext fVk;
|
||||
bool fOwnsContext;
|
||||
protected:
|
||||
VkTestContext(const GrVkBackendContext& vk, const GrVkExtensions* extensions, bool ownsContext,
|
||||
VkDebugReportCallbackEXT debugCallback)
|
||||
: fVk(vk)
|
||||
, fExtensions(extensions)
|
||||
, fOwnsContext(ownsContext)
|
||||
, fDebugCallback(debugCallback) {}
|
||||
|
||||
GrVkBackendContext fVk;
|
||||
const GrVkExtensions* fExtensions;
|
||||
bool fOwnsContext;
|
||||
VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
|
||||
|
||||
private:
|
||||
|
@ -59,36 +59,22 @@ 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
|
||||
|
||||
// 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; \
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_ENABLE_VK_LAYERS
|
||||
return false;
|
||||
}
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
|
||||
VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objectType,
|
||||
@ -112,6 +98,202 @@ 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(GrVkGetProc 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(GrVkGetProc 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)); \
|
||||
@ -134,6 +316,7 @@ static void destroy_instance(GrVkGetProc getProc, VkInstance inst,
|
||||
|
||||
bool CreateVkBackendContext(GrVkGetProc getProc,
|
||||
GrVkBackendContext* ctx,
|
||||
GrVkExtensions* extensions,
|
||||
VkDebugReportCallbackEXT* debugCallback,
|
||||
uint32_t* presentQueueIndexPtr,
|
||||
CanPresentFn canPresent) {
|
||||
@ -152,50 +335,25 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
|
||||
kGrVkMinimumVersion, // apiVersion
|
||||
};
|
||||
|
||||
GrVkExtensions extensions(getProc);
|
||||
extensions.initInstance(kGrVkMinimumVersion);
|
||||
SkTArray<VkLayerProperties> instanceLayers;
|
||||
SkTArray<VkExtensionProperties> instanceExtensions;
|
||||
|
||||
if (!init_instance_extensions_and_layers(getProc, kGrVkMinimumVersion,
|
||||
&instanceExtensions,
|
||||
&instanceLayers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkTArray<const char*> instanceLayerNames;
|
||||
SkTArray<const char*> instanceExtensionNames;
|
||||
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]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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
|
||||
@ -208,6 +366,8 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
|
||||
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) {
|
||||
@ -241,7 +401,6 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
|
||||
}
|
||||
#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);
|
||||
@ -323,17 +482,29 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
|
||||
presentQueueIndex = graphicsQueueIndex;
|
||||
}
|
||||
|
||||
extensions.initDevice(kGrVkMinimumVersion, inst, physDev);
|
||||
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;
|
||||
}
|
||||
|
||||
SkTArray<const char*> deviceLayerNames;
|
||||
SkTArray<const char*> deviceExtensionNames;
|
||||
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 < deviceLayers.count(); ++i) {
|
||||
deviceLayerNames.push_back(deviceLayers[i].layerName);
|
||||
}
|
||||
if (extensions.hasDeviceExtension("VK_NV_glsl_shader")) {
|
||||
deviceExtensionNames.push_back("VK_NV_glsl_shader");
|
||||
extensionFlags |= kNV_glsl_shader_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);
|
||||
}
|
||||
}
|
||||
|
||||
// query to get the physical device properties
|
||||
@ -400,13 +571,18 @@ bool CreateVkBackendContext(GrVkGetProc getProc,
|
||||
VkQueue queue;
|
||||
grVkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue);
|
||||
|
||||
extensions->init((uint32_t) instanceExtensionNames.count(),
|
||||
instanceExtensionNames.begin(),
|
||||
(uint32_t) deviceExtensionNames.count(),
|
||||
deviceExtensionNames.begin());
|
||||
|
||||
ctx->fInstance = inst;
|
||||
ctx->fPhysicalDevice = physDev;
|
||||
ctx->fDevice = device;
|
||||
ctx->fQueue = queue;
|
||||
ctx->fGraphicsQueueIndex = graphicsQueueIndex;
|
||||
ctx->fMinAPIVersion = kGrVkMinimumVersion;
|
||||
ctx->fExtensions = extensionFlags;
|
||||
ctx->fVkExtensions = extensions;
|
||||
ctx->fFeatures = featureFlags;
|
||||
ctx->fGetProc = getProc;
|
||||
ctx->fOwnsInstanceAndDevice = false;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "vk/GrVkTypes.h"
|
||||
#include <functional>
|
||||
|
||||
class GrVkExtensions;
|
||||
struct GrVkBackendContext;
|
||||
|
||||
namespace sk_gpu_test {
|
||||
@ -27,6 +28,7 @@ namespace sk_gpu_test {
|
||||
|
||||
bool CreateVkBackendContext(GrVkGetProc getProc,
|
||||
GrVkBackendContext* ctx,
|
||||
GrVkExtensions*,
|
||||
VkDebugReportCallbackEXT* debugCallback,
|
||||
uint32_t* presentQueueIndexPtr = nullptr,
|
||||
CanPresentFn canPresent = CanPresentFn());
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "SkSurface.h"
|
||||
#include "VulkanWindowContext.h"
|
||||
|
||||
#include "vk/GrVkExtensions.h"
|
||||
#include "vk/GrVkImage.h"
|
||||
#include "vk/GrVkUtil.h"
|
||||
#include "vk/GrVkTypes.h"
|
||||
@ -59,14 +60,14 @@ void VulkanWindowContext::initializeContext() {
|
||||
return getInstanceProc(instance, proc_name);
|
||||
};
|
||||
GrVkBackendContext backendContext;
|
||||
if (!sk_gpu_test::CreateVkBackendContext(getProc,
|
||||
&backendContext, &fDebugCallback,
|
||||
GrVkExtensions extensions;
|
||||
if (!sk_gpu_test::CreateVkBackendContext(getProc, &backendContext, &extensions, &fDebugCallback,
|
||||
&fPresentQueueIndex, fCanPresentFn)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(backendContext.fExtensions & kKHR_surface_GrVkExtensionFlag) ||
|
||||
!(backendContext.fExtensions & kKHR_swapchain_GrVkExtensionFlag)) {
|
||||
if (!extensions.hasExtension(VK_KHR_SURFACE_EXTENSION_NAME) ||
|
||||
!extensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -76,7 +77,7 @@ void VulkanWindowContext::initializeContext() {
|
||||
fGraphicsQueueIndex = backendContext.fGraphicsQueueIndex;
|
||||
fGraphicsQueue = backendContext.fQueue;
|
||||
fInterface.reset(new GrVkInterface(backendContext.fGetProc, fInstance, fDevice,
|
||||
backendContext.fExtensions));
|
||||
&extensions));
|
||||
|
||||
GET_PROC(DestroyInstance);
|
||||
GET_PROC(DestroySurfaceKHR);
|
||||
|
Loading…
Reference in New Issue
Block a user