| /* |
| * MVKLayers.mm |
| * |
| * Copyright (c) 2014-2018 The Brenwill Workshop Ltd. (http://www.brenwill.com) |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "MVKLayers.h" |
| #include "MVKEnvironment.h" |
| #include "vk_mvk_moltenvk.h" |
| #include <mutex> |
| |
| using namespace std; |
| |
| |
| #pragma mark MVKLayer |
| |
| const char* MVKLayer::getName() { return (const char*)&_layerProperties.layerName; } |
| |
| VkLayerProperties* const MVKLayer::getLayerProperties() { return &_layerProperties; } |
| |
| VkResult MVKLayer::getExtensionProperties(uint32_t* pCount, VkExtensionProperties* pProperties) { |
| |
| // If properties aren't actually being requested yet, simply update the returned count |
| if ( !pProperties ) { |
| *pCount = (uint32_t)_extensions.size(); |
| return VK_SUCCESS; |
| } |
| |
| // Othewise, determine how many extensions we'll return, and return that count |
| uint32_t extCnt = (uint32_t)_extensions.size(); |
| VkResult result = (*pCount <= extCnt) ? VK_SUCCESS : VK_INCOMPLETE; |
| *pCount = min(extCnt, *pCount); |
| |
| // Now populate the layer properties |
| for (uint32_t extIdx = 0; extIdx < *pCount; extIdx++) { |
| pProperties[extIdx] = _extensions[extIdx]; |
| } |
| |
| return result; |
| } |
| |
| bool MVKLayer::hasExtensionNamed(const char* extnName) { |
| for (auto& extn : _extensions) { |
| if ( strcmp(extn.extensionName, extnName) == 0 ) { return true; } |
| } |
| return false; |
| } |
| |
| |
| #pragma mark Object Creation |
| |
| MVKLayer::MVKLayer() { |
| |
| // The core driver layer |
| strcpy(_layerProperties.layerName, "MoltenVK"); |
| strcpy(_layerProperties.description, "MoltenVK driver layer"); |
| _layerProperties.specVersion = MVK_VULKAN_API_VERSION; |
| _layerProperties.implementationVersion = MVK_VERSION; |
| |
| // Extensions |
| VkExtensionProperties extTmplt; |
| |
| memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName)); |
| strcpy(extTmplt.extensionName, VK_MVK_MOLTENVK_EXTENSION_NAME); |
| extTmplt.specVersion = VK_MVK_MOLTENVK_SPEC_VERSION; |
| _extensions.push_back(extTmplt); |
| |
| memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName)); |
| strcpy(extTmplt.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME); |
| extTmplt.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION; |
| _extensions.push_back(extTmplt); |
| |
| memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName)); |
| strcpy(extTmplt.extensionName, VK_KHR_SURFACE_EXTENSION_NAME); |
| extTmplt.specVersion = VK_KHR_SURFACE_SPEC_VERSION; |
| _extensions.push_back(extTmplt); |
| |
| memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName)); |
| strcpy(extTmplt.extensionName, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME); |
| extTmplt.specVersion = VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION; |
| _extensions.push_back(extTmplt); |
| |
| #if MVK_IOS |
| memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName)); |
| strcpy(extTmplt.extensionName, VK_MVK_IOS_SURFACE_EXTENSION_NAME); |
| extTmplt.specVersion = VK_MVK_IOS_SURFACE_SPEC_VERSION; |
| _extensions.push_back(extTmplt); |
| |
| memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName)); |
| strcpy(extTmplt.extensionName, VK_IMG_FORMAT_PVRTC_EXTENSION_NAME); |
| extTmplt.specVersion = VK_IMG_FORMAT_PVRTC_SPEC_VERSION; |
| _extensions.push_back(extTmplt); |
| #endif |
| #if MVK_MACOS |
| memset(extTmplt.extensionName, 0, sizeof(extTmplt.extensionName)); |
| strcpy(extTmplt.extensionName, VK_MVK_MACOS_SURFACE_EXTENSION_NAME); |
| extTmplt.specVersion = VK_MVK_MACOS_SURFACE_SPEC_VERSION; |
| _extensions.push_back(extTmplt); |
| #endif |
| } |
| |
| |
| #pragma mark MVKLayerManager |
| |
| MVKLayer* MVKLayerManager::getDriverLayer() { return &(_layers[0]); } |
| |
| MVKLayer* MVKLayerManager::getLayerNamed(const char* pLayerName) { |
| |
| // If name is null, return the driver layer |
| if ( !pLayerName ) { return getDriverLayer(); } |
| |
| // Otherwise look for a layer with the specified name |
| uint32_t layCnt = (uint32_t)_layers.size(); |
| for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) { |
| MVKLayer* pLayer = &_layers[layIdx]; |
| if ( strcmp(pLayer->getName(), pLayerName) == 0 ) { return pLayer; } |
| } |
| return VK_NULL_HANDLE; |
| } |
| |
| |
| VkResult MVKLayerManager::getLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties) { |
| |
| // If properties aren't actually being requested yet, simply update the returned count |
| if ( !pProperties ) { |
| *pCount = (uint32_t)_layers.size(); |
| return VK_SUCCESS; |
| } |
| |
| // Othewise, determine how many layers we'll return, and return that count |
| uint32_t layerCnt = (uint32_t)_layers.size(); |
| VkResult result = (*pCount <= layerCnt) ? VK_SUCCESS : VK_INCOMPLETE; |
| *pCount = min(layerCnt, *pCount); |
| |
| // Now populate the layer properties |
| for (uint32_t layIdx = 0; layIdx < *pCount; layIdx++) { |
| pProperties[layIdx] = *(&_layers[layIdx])->getLayerProperties(); |
| } |
| |
| return result; |
| } |
| |
| |
| #pragma mark Object Creation |
| |
| // Populate the layers |
| MVKLayerManager::MVKLayerManager() { |
| _layers.push_back(MVKLayer()); |
| } |
| |
| static mutex _lock; |
| static MVKLayerManager* _globalManager = VK_NULL_HANDLE; |
| |
| MVKLayerManager* MVKLayerManager::globalManager() { |
| lock_guard<mutex> lock(_lock); |
| if ( !_globalManager ) { _globalManager = new MVKLayerManager(); } |
| return _globalManager; |
| } |
| |
| |