Commit 02cc1cd6 authored by WuZhiwen's avatar WuZhiwen Committed by Alexander Alekhin

Merge pull request #13244 from wzw-intel:init_vulkan

* dnn/Vulkan: don't init Vulkan runtime if using other backend/target

Don't need to explictly call a init API but will automatically
init Vulkan environment the first time to use an VkCom object.
Signed-off-by: 's avatarWu Zhiwen <zhiwen.wu@intel.com>

* dnn/Vulkan: depress compilier warning for "-Wsign-promo"
Signed-off-by: 's avatarWu Zhiwen <zhiwen.wu@intel.com>
parent 0e6cf419
...@@ -911,21 +911,8 @@ struct Net::Impl ...@@ -911,21 +911,8 @@ struct Net::Impl
typedef std::map<int, LayerShapes> LayersShapesMap; typedef std::map<int, LayerShapes> LayersShapesMap;
typedef std::map<int, LayerData> MapIdToLayerData; typedef std::map<int, LayerData> MapIdToLayerData;
~Impl()
{
#ifdef HAVE_VULKAN
// Vulkan requires explicit releasing the child objects of
// VkDevice object prior to releasing VkDevice object itself.
layers.clear();
backendWrappers.clear();
vkcom::deinitPerThread();
#endif
}
Impl() Impl()
{ {
#ifdef HAVE_VULKAN
vkcom::initPerThread();
#endif
//allocate fake net input layer //allocate fake net input layer
netInputLayer = Ptr<DataLayer>(new DataLayer()); netInputLayer = Ptr<DataLayer>(new DataLayer());
LayerData &inpl = layers.insert( make_pair(0, LayerData()) ).first->second; LayerData &inpl = layers.insert( make_pair(0, LayerData()) ).first->second;
......
...@@ -36,7 +36,6 @@ protected: ...@@ -36,7 +36,6 @@ protected:
void recordCommandBuffer(void* push_constants = NULL, size_t push_constants_size = 0); void recordCommandBuffer(void* push_constants = NULL, size_t push_constants_size = 0);
void runCommandBuffer(); void runCommandBuffer();
const Context* ctx_;
VkPipeline pipeline_; VkPipeline pipeline_;
VkCommandBuffer cmd_buffer_; VkCommandBuffer cmd_buffer_;
VkDescriptorPool descriptor_pool_; VkDescriptorPool descriptor_pool_;
......
...@@ -39,9 +39,6 @@ enum PaddingMode { kPaddingModeSame, kPaddingModeValid, kPaddingModeCaffe, kPadd ...@@ -39,9 +39,6 @@ enum PaddingMode { kPaddingModeSame, kPaddingModeValid, kPaddingModeCaffe, kPadd
enum FusedActivationType { kNone, kRelu, kRelu1, kRelu6, kActivationNum }; enum FusedActivationType { kNone, kRelu, kRelu1, kRelu6, kActivationNum };
typedef std::vector<int> Shape; typedef std::vector<int> Shape;
/* context APIs */
bool initPerThread();
void deinitPerThread();
bool isAvailable(); bool isAvailable();
#endif // HAVE_VULKAN #endif // HAVE_VULKAN
......
...@@ -18,7 +18,7 @@ static uint32_t findMemoryType(uint32_t memoryTypeBits, VkMemoryPropertyFlags pr ...@@ -18,7 +18,7 @@ static uint32_t findMemoryType(uint32_t memoryTypeBits, VkMemoryPropertyFlags pr
{ {
VkPhysicalDeviceMemoryProperties memoryProperties; VkPhysicalDeviceMemoryProperties memoryProperties;
vkGetPhysicalDeviceMemoryProperties(getPhysicalDevice(), &memoryProperties); vkGetPhysicalDeviceMemoryProperties(kPhysicalDevice, &memoryProperties);
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) { for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) {
if ((memoryTypeBits & (1 << i)) && if ((memoryTypeBits & (1 << i)) &&
......
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
namespace cv { namespace dnn { namespace vkcom { namespace cv { namespace dnn { namespace vkcom {
#ifdef HAVE_VULKAN #ifdef HAVE_VULKAN
extern VkPhysicalDevice kPhysicalDevice;
extern VkDevice kDevice;
extern VkQueue kQueue;
extern VkCommandPool kCmdPool;
enum ShapeIdx enum ShapeIdx
{ {
...@@ -42,7 +46,7 @@ enum ShapeIdx ...@@ -42,7 +46,7 @@ enum ShapeIdx
{ \ { \
if (f != VK_SUCCESS) \ if (f != VK_SUCCESS) \
{ \ { \
CV_LOG_ERROR(NULL, "Vulkan check failed, result = " << f); \ CV_LOG_ERROR(NULL, "Vulkan check failed, result = " << (int)f); \
CV_Error(Error::StsError, "Vulkan check failed"); \ CV_Error(Error::StsError, "Vulkan check failed"); \
} \ } \
} }
......
...@@ -6,396 +6,289 @@ ...@@ -6,396 +6,289 @@
// Third party copyrights are property of their respective owners. // Third party copyrights are property of their respective owners.
#include "../../precomp.hpp" #include "../../precomp.hpp"
#include "common.hpp"
#include "internal.hpp"
#include "../include/op_conv.hpp"
#include "../include/op_pool.hpp"
#include "../include/op_lrn.hpp"
#include "../include/op_concat.hpp"
#include "../include/op_softmax.hpp"
#include "../vulkan/vk_loader.hpp" #include "../vulkan/vk_loader.hpp"
#include "common.hpp"
#include "context.hpp"
namespace cv { namespace dnn { namespace vkcom { namespace cv { namespace dnn { namespace vkcom {
#ifdef HAVE_VULKAN #ifdef HAVE_VULKAN
static bool enableValidationLayers = false; std::shared_ptr<Context> kCtx;
static VkInstance kInstance; bool enableValidationLayers = false;
static VkPhysicalDevice kPhysicalDevice; VkInstance kInstance;
static VkDebugReportCallbackEXT kDebugReportCallback; VkPhysicalDevice kPhysicalDevice;
static uint32_t kQueueFamilyIndex; VkDevice kDevice;
VkQueue kQueue;
VkCommandPool kCmdPool;
VkDebugReportCallbackEXT kDebugReportCallback;
uint32_t kQueueFamilyIndex;
std::vector<const char *> kEnabledLayers; std::vector<const char *> kEnabledLayers;
typedef std::map<std::thread::id, Context*> IdToContextMap; std::map<std::string, std::vector<uint32_t>> kShaders;
IdToContextMap kThreadResources;
static std::map<std::string, std::vector<uint32_t>> kShaders; static uint32_t getComputeQueueFamilyIndex()
static int init_count = 0;
static bool init();
static void release();
static uint32_t getComputeQueueFamilyIndex();
static bool checkExtensionAvailability(const char *extension_name,
const std::vector<VkExtensionProperties>
&available_extensions);
static VKAPI_ATTR VkBool32 VKAPI_CALL debugReportCallbackFn(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
void* pUserData);
static void setContext(Context* ctx)
{ {
cv::AutoLock lock(getInitializationMutex()); uint32_t queueFamilyCount;
std::thread::id tid = std::this_thread::get_id();
if (kThreadResources.find(tid) != kThreadResources.end()) vkGetPhysicalDeviceQueueFamilyProperties(kPhysicalDevice, &queueFamilyCount, NULL);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(kPhysicalDevice,
&queueFamilyCount,
queueFamilies.data());
uint32_t i = 0;
for (; i < queueFamilies.size(); ++i)
{ {
return; VkQueueFamilyProperties props = queueFamilies[i];
if (props.queueCount > 0 && (props.queueFlags & VK_QUEUE_COMPUTE_BIT))
{
break;
}
}
if (i == queueFamilies.size())
{
throw std::runtime_error("could not find a queue family that supports operations");
} }
kThreadResources.insert(std::pair<std::thread::id, Context*>(tid, ctx));
return i;
} }
Context* getContext() bool checkExtensionAvailability(const char *extension_name,
const std::vector<VkExtensionProperties> &available_extensions)
{ {
Context* ctx = NULL; for( size_t i = 0; i < available_extensions.size(); ++i )
cv::AutoLock lock(getInitializationMutex());
std::thread::id tid = std::this_thread::get_id();
IdToContextMap::iterator it = kThreadResources.find(tid);
if (it != kThreadResources.end())
{ {
ctx = it->second; if( strcmp( available_extensions[i].extensionName, extension_name ) == 0 )
{
return true;
}
} }
return ctx; return false;
}
VKAPI_ATTR VkBool32 VKAPI_CALL debugReportCallbackFn(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
void* pUserData)
{
std::cout << "Debug Report: " << pLayerPrefix << ":" << pMessage << std::endl;
return VK_FALSE;
} }
static void removeContext() // internally used
void createContext()
{ {
cv::AutoLock lock(getInitializationMutex()); cv::AutoLock lock(getInitializationMutex());
std::thread::id tid = std::this_thread::get_id(); if (!kCtx)
IdToContextMap::iterator it = kThreadResources.find(tid);
if (it == kThreadResources.end())
{ {
return; kCtx.reset(new Context());
} }
kThreadResources.erase(it);
} }
bool initPerThread() bool isAvailable()
{ {
VkDevice device; try
VkQueue queue;
VkCommandPool cmd_pool;
VKCOM_CHECK_BOOL_RET_VAL(init(), false);
Context* ctx = getContext();
if (ctx)
{ {
ctx->ref++; createContext();
return true; }
catch (const cv::Exception& e)
{
CV_LOG_ERROR(NULL, "Failed to init Vulkan environment. " << e.what());
return false;
} }
// create device, queue, command pool
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = kQueueFamilyIndex;
queueCreateInfo.queueCount = 1; // create one queue in this family. We don't need more.
float queuePriorities = 1.0; // we only have one queue, so this is not that imporant.
queueCreateInfo.pQueuePriorities = &queuePriorities;
VkDeviceCreateInfo deviceCreateInfo = {};
// Specify any desired device features here. We do not need any for this application, though.
VkPhysicalDeviceFeatures deviceFeatures = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.enabledLayerCount = kEnabledLayers.size();
deviceCreateInfo.ppEnabledLayerNames = kEnabledLayers.data();
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
VK_CHECK_RESULT(vkCreateDevice(kPhysicalDevice, &deviceCreateInfo, NULL, &device));
// Get a handle to the only member of the queue family.
vkGetDeviceQueue(device, kQueueFamilyIndex, 0, &queue);
// create command pool
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
// the queue family of this command pool. All command buffers allocated from this command pool,
// must be submitted to queues of this family ONLY.
commandPoolCreateInfo.queueFamilyIndex = kQueueFamilyIndex;
VK_CHECK_RESULT(vkCreateCommandPool(device, &commandPoolCreateInfo, NULL, &cmd_pool));
ctx = new Context();
ctx->device = device;
ctx->queue = queue;
ctx->cmd_pool = cmd_pool;
ctx->ref = 1;
setContext(ctx);
return true; return true;
} }
void deinitPerThread() Context::Context()
{ {
Context* ctx = getContext(); if(!loadVulkanLibrary())
if (ctx == NULL)
{ {
release(); CV_Error(Error::StsError, "loadVulkanLibrary failed");
return; return;
} }
else if (!loadVulkanEntry())
if (ctx->ref > 1)
{ {
ctx->ref--; CV_Error(Error::StsError, "loadVulkanEntry failed");
return;
} }
else if (ctx->ref == 1) else if (!loadVulkanGlobalFunctions())
{ {
for(auto &kv: ctx->shader_modules) CV_Error(Error::StsError, "loadVulkanGlobalFunctions failed");
{ return;
vkDestroyShaderModule(ctx->device, kv.second, NULL);
}
ctx->shader_modules.clear();
vkDestroyCommandPool(ctx->device, ctx->cmd_pool, NULL);
vkDestroyDevice(ctx->device, NULL);
removeContext();
delete ctx;
} }
else
CV_Assert(0);
release();
}
static bool init() // create VkInstance, VkPhysicalDevice
{ std::vector<const char *> enabledExtensions;
cv::AutoLock lock(getInitializationMutex()); if (enableValidationLayers)
if (init_count == 0)
{ {
if(!loadVulkanLibrary()) uint32_t layerCount;
{ vkEnumerateInstanceLayerProperties(&layerCount, NULL);
return false;
}
else if (!loadVulkanEntry())
{
return false;
}
else if (!loadVulkanGlobalFunctions())
{
return false;
}
// create VkInstance, VkPhysicalDevice std::vector<VkLayerProperties> layerProperties(layerCount);
std::vector<const char *> enabledExtensions; vkEnumerateInstanceLayerProperties(&layerCount, layerProperties.data());
if (enableValidationLayers)
{
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount, NULL);
std::vector<VkLayerProperties> layerProperties(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, layerProperties.data());
bool foundLayer = false;
for (VkLayerProperties prop : layerProperties)
{
if (strcmp("VK_LAYER_LUNARG_standard_validation", prop.layerName) == 0)
{
foundLayer = true;
break;
}
}
if (!foundLayer) bool foundLayer = false;
{ for (VkLayerProperties prop : layerProperties)
throw std::runtime_error("Layer VK_LAYER_LUNARG_standard_validation not supported\n"); {
} if (strcmp("VK_LAYER_LUNARG_standard_validation", prop.layerName) == 0)
kEnabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");
uint32_t extensionCount;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, NULL);
std::vector<VkExtensionProperties> extensionProperties(extensionCount);
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensionProperties.data());
bool foundExtension = false;
for (VkExtensionProperties prop : extensionProperties)
{ {
if (strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, prop.extensionName) == 0) foundLayer = true;
{ break;
foundExtension = true;
break;
}
}
if (!foundExtension) {
throw std::runtime_error("Extension VK_EXT_DEBUG_REPORT_EXTENSION_NAME not supported\n");
} }
enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
}
VkApplicationInfo applicationInfo = {};
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
applicationInfo.pApplicationName = "VkCom Library";
applicationInfo.applicationVersion = 0;
applicationInfo.pEngineName = "vkcom";
applicationInfo.engineVersion = 0;
applicationInfo.apiVersion = VK_API_VERSION_1_0;;
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.flags = 0;
createInfo.pApplicationInfo = &applicationInfo;
// Give our desired layers and extensions to vulkan.
createInfo.enabledLayerCount = kEnabledLayers.size();
createInfo.ppEnabledLayerNames = kEnabledLayers.data();
createInfo.enabledExtensionCount = enabledExtensions.size();
createInfo.ppEnabledExtensionNames = enabledExtensions.data();
VK_CHECK_RESULT(vkCreateInstance(&createInfo, NULL, &kInstance));
if (!loadVulkanFunctions(kInstance))
{
return false;
} }
if (enableValidationLayers && vkCreateDebugReportCallbackEXT) if (!foundLayer)
{ {
VkDebugReportCallbackCreateInfoEXT createInfo = {}; throw std::runtime_error("Layer VK_LAYER_LUNARG_standard_validation not supported\n");
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
createInfo.pfnCallback = &debugReportCallbackFn;
// Create and register callback.
VK_CHECK_RESULT(vkCreateDebugReportCallbackEXT(kInstance, &createInfo,
NULL, &kDebugReportCallback));
} }
kEnabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");
// find physical device uint32_t extensionCount;
uint32_t deviceCount;
vkEnumeratePhysicalDevices(kInstance, &deviceCount, NULL);
if (deviceCount == 0)
{
throw std::runtime_error("could not find a device with vulkan support");
}
std::vector<VkPhysicalDevice> devices(deviceCount); vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, NULL);
vkEnumeratePhysicalDevices(kInstance, &deviceCount, devices.data()); std::vector<VkExtensionProperties> extensionProperties(extensionCount);
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensionProperties.data());
for (VkPhysicalDevice device : devices) bool foundExtension = false;
for (VkExtensionProperties prop : extensionProperties)
{ {
if (true) if (strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, prop.extensionName) == 0)
{ {
kPhysicalDevice = device; foundExtension = true;
break; break;
} }
} }
kQueueFamilyIndex = getComputeQueueFamilyIndex(); if (!foundExtension) {
throw std::runtime_error("Extension VK_EXT_DEBUG_REPORT_EXTENSION_NAME not supported\n");
}
enabledExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
} }
init_count++; VkApplicationInfo applicationInfo = {};
return true; applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
} applicationInfo.pApplicationName = "VkCom Library";
applicationInfo.applicationVersion = 0;
applicationInfo.pEngineName = "vkcom";
applicationInfo.engineVersion = 0;
applicationInfo.apiVersion = VK_API_VERSION_1_0;;
static void release() VkInstanceCreateInfo createInfo = {};
{ createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
cv::AutoLock lock(getInitializationMutex()); createInfo.flags = 0;
if (init_count == 0) createInfo.pApplicationInfo = &applicationInfo;
// Give our desired layers and extensions to vulkan.
createInfo.enabledLayerCount = kEnabledLayers.size();
createInfo.ppEnabledLayerNames = kEnabledLayers.data();
createInfo.enabledExtensionCount = enabledExtensions.size();
createInfo.ppEnabledExtensionNames = enabledExtensions.data();
VK_CHECK_RESULT(vkCreateInstance(&createInfo, NULL, &kInstance));
if (!loadVulkanFunctions(kInstance))
{ {
CV_Error(Error::StsError, "loadVulkanFunctions failed");
return; return;
} }
init_count--; if (enableValidationLayers && vkCreateDebugReportCallbackEXT)
if (init_count == 0)
{ {
if (enableValidationLayers) { VkDebugReportCallbackCreateInfoEXT createInfo = {};
auto func = (PFN_vkDestroyDebugReportCallbackEXT) createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
vkGetInstanceProcAddr(kInstance, "vkDestroyDebugReportCallbackEXT"); createInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
if (func == nullptr) { VK_DEBUG_REPORT_WARNING_BIT_EXT |
throw std::runtime_error("Could not load vkDestroyDebugReportCallbackEXT"); VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
} createInfo.pfnCallback = &debugReportCallbackFn;
func(kInstance, kDebugReportCallback, NULL);
} // Create and register callback.
kShaders.clear(); VK_CHECK_RESULT(vkCreateDebugReportCallbackEXT(kInstance, &createInfo,
vkDestroyInstance(kInstance, NULL); NULL, &kDebugReportCallback));
} }
return; // find physical device
} uint32_t deviceCount;
vkEnumeratePhysicalDevices(kInstance, &deviceCount, NULL);
// Returns the index of a queue family that supports compute operations. if (deviceCount == 0)
static uint32_t getComputeQueueFamilyIndex() {
{ throw std::runtime_error("could not find a device with vulkan support");
uint32_t queueFamilyCount; }
vkGetPhysicalDeviceQueueFamilyProperties(kPhysicalDevice, &queueFamilyCount, NULL);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount); std::vector<VkPhysicalDevice> devices(deviceCount);
vkGetPhysicalDeviceQueueFamilyProperties(kPhysicalDevice, vkEnumeratePhysicalDevices(kInstance, &deviceCount, devices.data());
&queueFamilyCount,
queueFamilies.data());
uint32_t i = 0; for (VkPhysicalDevice device : devices)
for (; i < queueFamilies.size(); ++i)
{ {
VkQueueFamilyProperties props = queueFamilies[i]; if (true)
if (props.queueCount > 0 && (props.queueFlags & VK_QUEUE_COMPUTE_BIT))
{ {
kPhysicalDevice = device;
break; break;
} }
} }
if (i == queueFamilies.size()) kQueueFamilyIndex = getComputeQueueFamilyIndex();
{
throw std::runtime_error("could not find a queue family that supports operations");
}
return i; // create device, queue, command pool
} VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = kQueueFamilyIndex;
queueCreateInfo.queueCount = 1; // create one queue in this family. We don't need more.
float queuePriorities = 1.0; // we only have one queue, so this is not that imporant.
queueCreateInfo.pQueuePriorities = &queuePriorities;
bool checkExtensionAvailability(const char *extension_name, VkDeviceCreateInfo deviceCreateInfo = {};
const std::vector<VkExtensionProperties> &available_extensions)
{
for( size_t i = 0; i < available_extensions.size(); ++i )
{
if( strcmp( available_extensions[i].extensionName, extension_name ) == 0 )
{
return true;
}
}
return false;
}
VKAPI_ATTR VkBool32 VKAPI_CALL debugReportCallbackFn( // Specify any desired device features here. We do not need any for this application, though.
VkDebugReportFlagsEXT flags, VkPhysicalDeviceFeatures deviceFeatures = {};
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
void* pUserData)
{
std::cout << "Debug Report: " << pLayerPrefix << ":" << pMessage << std::endl;
return VK_FALSE;
}
// internally used functions deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
VkPhysicalDevice getPhysicalDevice() deviceCreateInfo.enabledLayerCount = kEnabledLayers.size();
{ deviceCreateInfo.ppEnabledLayerNames = kEnabledLayers.data();
return kPhysicalDevice; deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
VK_CHECK_RESULT(vkCreateDevice(kPhysicalDevice, &deviceCreateInfo, NULL, &kDevice));
// Get a handle to the only member of the queue family.
vkGetDeviceQueue(kDevice, kQueueFamilyIndex, 0, &kQueue);
// create command pool
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
// the queue family of this command pool. All command buffers allocated from this command pool,
// must be submitted to queues of this family ONLY.
commandPoolCreateInfo.queueFamilyIndex = kQueueFamilyIndex;
VK_CHECK_RESULT(vkCreateCommandPool(kDevice, &commandPoolCreateInfo, NULL, &kCmdPool));
} }
bool isAvailable() Context::~Context()
{ {
return getContext() != NULL; vkDestroyCommandPool(kDevice, kCmdPool, NULL);
vkDestroyDevice(kDevice, NULL);
if (enableValidationLayers) {
auto func = (PFN_vkDestroyDebugReportCallbackEXT)
vkGetInstanceProcAddr(kInstance, "vkDestroyDebugReportCallbackEXT");
if (func == nullptr) {
throw std::runtime_error("Could not load vkDestroyDebugReportCallbackEXT");
}
func(kInstance, kDebugReportCallback, NULL);
}
kShaders.clear();
vkDestroyInstance(kInstance, NULL);
return;
} }
#endif // HAVE_VULKAN #endif // HAVE_VULKAN
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#ifndef OPENCV_DNN_VKCOM_CONTEXT_HPP #ifndef OPENCV_DNN_VKCOM_CONTEXT_HPP
#define OPENCV_DNN_VKCOM_CONTEXT_HPP #define OPENCV_DNN_VKCOM_CONTEXT_HPP
#include "common.hpp"
namespace cv { namespace dnn { namespace vkcom { namespace cv { namespace dnn { namespace vkcom {
...@@ -15,13 +14,12 @@ namespace cv { namespace dnn { namespace vkcom { ...@@ -15,13 +14,12 @@ namespace cv { namespace dnn { namespace vkcom {
struct Context struct Context
{ {
VkDevice device; Context();
VkQueue queue; ~Context();
VkCommandPool cmd_pool;
std::map<std::string, VkShaderModule> shader_modules;
int ref;
}; };
void createContext();
#endif // HAVE_VULKAN #endif // HAVE_VULKAN
}}} // namespace cv::dnn::vkcom }}} // namespace cv::dnn::vkcom
......
...@@ -16,8 +16,8 @@ namespace cv { namespace dnn { namespace vkcom { ...@@ -16,8 +16,8 @@ namespace cv { namespace dnn { namespace vkcom {
OpBase::OpBase() OpBase::OpBase()
{ {
ctx_ = getContext(); createContext();
device_ = ctx_->device; device_ = kDevice;
pipeline_ = VK_NULL_HANDLE; pipeline_ = VK_NULL_HANDLE;
cmd_buffer_ = VK_NULL_HANDLE; cmd_buffer_ = VK_NULL_HANDLE;
descriptor_pool_ = VK_NULL_HANDLE; descriptor_pool_ = VK_NULL_HANDLE;
...@@ -139,7 +139,7 @@ void OpBase::createCommandBuffer() ...@@ -139,7 +139,7 @@ void OpBase::createCommandBuffer()
{ {
VkCommandBufferAllocateInfo info = {}; VkCommandBufferAllocateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
info.commandPool = ctx_->cmd_pool; info.commandPool = kCmdPool;
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
info.commandBufferCount = 1; info.commandBufferCount = 1;
VK_CHECK_RESULT(vkAllocateCommandBuffers(device_, &info, &cmd_buffer_)); VK_CHECK_RESULT(vkAllocateCommandBuffers(device_, &info, &cmd_buffer_));
...@@ -176,7 +176,7 @@ void OpBase::runCommandBuffer() ...@@ -176,7 +176,7 @@ void OpBase::runCommandBuffer()
fence_create_info_.flags = 0; fence_create_info_.flags = 0;
VK_CHECK_RESULT(vkCreateFence(device_, &fence_create_info_, NULL, &fence)); VK_CHECK_RESULT(vkCreateFence(device_, &fence_create_info_, NULL, &fence));
VK_CHECK_RESULT(vkQueueSubmit(ctx_->queue, 1, &submit_info, fence)); VK_CHECK_RESULT(vkQueueSubmit(kQueue, 1, &submit_info, fence));
VK_CHECK_RESULT(vkWaitForFences(device_, 1, &fence, VK_TRUE, 100000000000)); VK_CHECK_RESULT(vkWaitForFences(device_, 1, &fence, VK_TRUE, 100000000000));
vkDestroyFence(device_, fence, NULL); vkDestroyFence(device_, fence, NULL);
} }
......
...@@ -15,15 +15,15 @@ namespace cv { namespace dnn { namespace vkcom { ...@@ -15,15 +15,15 @@ namespace cv { namespace dnn { namespace vkcom {
Tensor::Tensor(Format fmt) : size_in_byte_(0), format_(fmt) Tensor::Tensor(Format fmt) : size_in_byte_(0), format_(fmt)
{ {
Context *ctx = getContext(); createContext();
device_ = ctx->device; device_ = kDevice;
} }
Tensor::Tensor(const char* data, std::vector<int>& shape, Format fmt) Tensor::Tensor(const char* data, std::vector<int>& shape, Format fmt)
: size_in_byte_(0), format_(fmt) : size_in_byte_(0), format_(fmt)
{ {
Context *ctx = getContext(); createContext();
device_ = ctx->device; device_ = kDevice;
reshape(data, shape); reshape(data, shape);
} }
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#ifndef OPENCV_DNN_VKCOM_VULKAN_VK_LOADER_HPP #ifndef OPENCV_DNN_VKCOM_VULKAN_VK_LOADER_HPP
#define OPENCV_DNN_VKCOM_VULKAN_VK_LOADER_HPP #define OPENCV_DNN_VKCOM_VULKAN_VK_LOADER_HPP
#ifdef HAVE_VULKAN
#include <vulkan/vulkan.h>
#endif // HAVE_VULKAN
namespace cv { namespace dnn { namespace vkcom { namespace cv { namespace dnn { namespace vkcom {
#ifdef HAVE_VULKAN #ifdef HAVE_VULKAN
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment