| Index: src/gpu/vk/GrVkExtensions.cpp
|
| diff --git a/src/gpu/vk/GrVkExtensions.cpp b/src/gpu/vk/GrVkExtensions.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8fa99cf9fc073ae5dcd3e15b3bf53beedec0a39f
|
| --- /dev/null
|
| +++ b/src/gpu/vk/GrVkExtensions.cpp
|
| @@ -0,0 +1,252 @@
|
| +/*
|
| + * Copyright 2016 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "vk/GrVkExtensions.h"
|
| +#include "vk/GrVkUtil.h"
|
| +
|
| +#include "SkTSearch.h"
|
| +#include "SkTSort.h"
|
| +
|
| +namespace { // This cannot be static because it is used as a template parameter.
|
| +inline bool extension_compare(const SkString& a, const SkString& b) {
|
| + return strcmp(a.c_str(), b.c_str()) < 0;
|
| +}
|
| +}
|
| +
|
| +// finds the index of ext in strings or a negative result if ext is not found.
|
| +static int find_string(const SkTArray<SkString>& strings, const char ext[]) {
|
| + if (strings.empty()) {
|
| + return -1;
|
| + }
|
| + SkString extensionStr(ext);
|
| + int idx = SkTSearch<SkString, extension_compare>(&strings.front(),
|
| + strings.count(),
|
| + extensionStr,
|
| + sizeof(SkString));
|
| + return idx;
|
| +}
|
| +
|
| +GrVkExtensions::GrVkExtensions(const GrVkExtensions& that)
|
| + : fInstanceExtensionStrings(new SkTArray<SkString>)
|
| + , fDeviceExtensionStrings(new SkTArray<SkString>)
|
| + , fInstanceLayerStrings(new SkTArray<SkString>)
|
| + , fDeviceLayerStrings(new SkTArray<SkString>) {
|
| + *this = that;
|
| +}
|
| +
|
| +GrVkExtensions& GrVkExtensions::operator=(const GrVkExtensions& that) {
|
| + *fInstanceExtensionStrings = *that.fInstanceExtensionStrings;
|
| + *fDeviceExtensionStrings = *that.fDeviceExtensionStrings;
|
| + *fInstanceLayerStrings = *that.fInstanceLayerStrings;
|
| + *fDeviceLayerStrings = *that.fDeviceLayerStrings;
|
| +
|
| + fInitialized = that.fInitialized;
|
| + return *this;
|
| +}
|
| +
|
| +bool GrVkExtensions::init(
|
| + uint32_t specVersion,
|
| + PFN_vkEnumerateInstanceExtensionProperties enumerateInstanceExtensionProperties,
|
| + PFN_vkEnumerateDeviceExtensionProperties enumerateDeviceExtensionProperties,
|
| + PFN_vkEnumerateInstanceLayerProperties enumerateInstanceLayerProperties,
|
| + PFN_vkEnumerateDeviceLayerProperties enumerateDeviceLayerProperties) {
|
| + fInitialized = false;
|
| + this->reset();
|
| +
|
| + if (!enumerateInstanceExtensionProperties ||
|
| + !enumerateDeviceExtensionProperties ||
|
| + !enumerateInstanceLayerProperties ||
|
| + !enumerateDeviceLayerProperties) {
|
| + return false;
|
| + }
|
| +
|
| + // instance extensions
|
| + uint32_t extensionCount = 0;
|
| + VkResult res = enumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
|
| +
|
| + VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
|
| + res = enumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
|
| +
|
| + fInstanceExtensionStrings->push_back_n(extensionCount);
|
| + for (uint32_t i = 0; i < extensionCount; ++i) {
|
| + if (specVersion >= extensions[i].specVersion) {
|
| + (*fInstanceExtensionStrings)[i] = extensions[i].extensionName;
|
| + }
|
| + }
|
| + delete [] extensions;
|
| +
|
| + if (!fInstanceExtensionStrings->empty()) {
|
| + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
|
| + SkTQSort(&fInstanceExtensionStrings->front(), &fInstanceExtensionStrings->back(), cmp);
|
| + }
|
| +
|
| + fInitialized = true;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +bool GrVkExtensions::hasInstanceExtension(const char ext[]) const {
|
| + SkASSERT(fInitialized);
|
| +
|
| + return find_string(*fInstanceExtensionStrings, ext) >= 0;
|
| +}
|
| +
|
| +bool GrVkExtensions::hasDeviceExtension(const char ext[]) const {
|
| + SkASSERT(fInitialized);
|
| +
|
| + return find_string(*fDeviceExtensionStrings, ext) >= 0;
|
| +}
|
| +
|
| +bool GrVkExtensions::hasInstanceLayer(const char ext[]) const {
|
| + SkASSERT(fInitialized);
|
| +
|
| + return find_string(*fInstanceLayerStrings, ext) >= 0;
|
| +}
|
| +
|
| +bool GrVkExtensions::hasDeviceLayer(const char ext[]) const {
|
| + SkASSERT(fInitialized);
|
| +
|
| + return find_string(*fDeviceLayerStrings, ext) >= 0;
|
| +}
|
| +
|
| +
|
| +bool GrVkExtensions::removeInstanceExtension(const char ext[]) {
|
| + SkASSERT(fInitialized);
|
| + int idx = find_string(*fInstanceExtensionStrings, ext);
|
| + if (idx >= 0) {
|
| + // This is not terribly effecient but we really only expect this function to be called at
|
| + // most a handful of times when our test programs start.
|
| + SkAutoTDelete< SkTArray<SkString> > oldStrings(fInstanceExtensionStrings.release());
|
| + fInstanceExtensionStrings.reset(new SkTArray<SkString>(oldStrings->count() - 1));
|
| + fInstanceExtensionStrings->push_back_n(idx, &oldStrings->front());
|
| + fInstanceExtensionStrings->push_back_n(oldStrings->count() - idx-1, &(*oldStrings)[idx]+1);
|
| + return true;
|
| + } else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +bool GrVkExtensions::removeDeviceExtension(const char ext[]) {
|
| + SkASSERT(fInitialized);
|
| + int idx = find_string(*fDeviceExtensionStrings, ext);
|
| + if (idx >= 0) {
|
| + // This is not terribly effecient but we really only expect this function to be called at
|
| + // most a handful of times when our test programs start.
|
| + SkAutoTDelete< SkTArray<SkString> > oldStrings(fDeviceExtensionStrings.release());
|
| + fDeviceExtensionStrings.reset(new SkTArray<SkString>(oldStrings->count() - 1));
|
| + fDeviceExtensionStrings->push_back_n(idx, &oldStrings->front());
|
| + fDeviceExtensionStrings->push_back_n(oldStrings->count() - idx-1, &(*oldStrings)[idx] + 1);
|
| + return true;
|
| + }
|
| + else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +bool GrVkExtensions::removeInstanceLayer(const char ext[]) {
|
| + SkASSERT(fInitialized);
|
| + int idx = find_string(*fInstanceLayerStrings, ext);
|
| + if (idx >= 0) {
|
| + // This is not terribly effecient but we really only expect this function to be called at
|
| + // most a handful of times when our test programs start.
|
| + SkAutoTDelete< SkTArray<SkString> > oldStrings(fInstanceLayerStrings.release());
|
| + fInstanceLayerStrings.reset(new SkTArray<SkString>(oldStrings->count() - 1));
|
| + fInstanceLayerStrings->push_back_n(idx, &oldStrings->front());
|
| + fInstanceLayerStrings->push_back_n(oldStrings->count() - idx - 1, &(*oldStrings)[idx] + 1);
|
| + return true;
|
| + }
|
| + else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +bool GrVkExtensions::removeDeviceLayer(const char ext[]) {
|
| + SkASSERT(fInitialized);
|
| + int idx = find_string(*fDeviceLayerStrings, ext);
|
| + if (idx >= 0) {
|
| + // This is not terribly effecient but we really only expect this function to be called at
|
| + // most a handful of times when our test programs start.
|
| + SkAutoTDelete< SkTArray<SkString> > oldStrings(fDeviceLayerStrings.release());
|
| + fDeviceLayerStrings.reset(new SkTArray<SkString>(oldStrings->count() - 1));
|
| + fDeviceLayerStrings->push_back_n(idx, &oldStrings->front());
|
| + fDeviceLayerStrings->push_back_n(oldStrings->count() - idx - 1, &(*oldStrings)[idx] + 1);
|
| + return true;
|
| + }
|
| + else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +void GrVkExtensions::addInstanceExtension(const char ext[]) {
|
| + int idx = find_string(*fInstanceExtensionStrings, ext);
|
| + if (idx < 0) {
|
| + // This is not the most effecient approach since we end up doing a full sort of the
|
| + // extensions after the add
|
| + fInstanceExtensionStrings->push_back().set(ext);
|
| + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
|
| + SkTQSort(&fInstanceExtensionStrings->front(), &fInstanceExtensionStrings->back(), cmp);
|
| + }
|
| +}
|
| +
|
| +void GrVkExtensions::addDeviceExtension(const char ext[]) {
|
| + int idx = find_string(*fDeviceExtensionStrings, ext);
|
| + if (idx < 0) {
|
| + // This is not the most effecient approach since we end up doing a full sort of the
|
| + // extensions after the add
|
| + fDeviceExtensionStrings->push_back().set(ext);
|
| + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
|
| + SkTQSort(&fDeviceExtensionStrings->front(), &fDeviceExtensionStrings->back(), cmp);
|
| + }
|
| +}
|
| +
|
| +void GrVkExtensions::addInstanceLayer(const char ext[]) {
|
| + int idx = find_string(*fInstanceLayerStrings, ext);
|
| + if (idx < 0) {
|
| + // This is not the most effecient approach since we end up doing a full sort of the
|
| + // extensions after the add
|
| + fInstanceLayerStrings->push_back().set(ext);
|
| + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
|
| + SkTQSort(&fInstanceLayerStrings->front(), &fInstanceLayerStrings->back(), cmp);
|
| + }
|
| +}
|
| +
|
| +void GrVkExtensions::addDeviceLayer(const char ext[]) {
|
| + int idx = find_string(*fDeviceLayerStrings, ext);
|
| + if (idx < 0) {
|
| + // This is not the most effecient approach since we end up doing a full sort of the
|
| + // extensions after the add
|
| + fDeviceLayerStrings->push_back().set(ext);
|
| + SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
|
| + SkTQSort(&fDeviceLayerStrings->front(), &fDeviceLayerStrings->back(), cmp);
|
| + }
|
| +}
|
| +
|
| +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 : "");
|
| + }
|
| +}
|
|
|