Merge pull request #53 from billhollings/master

Populate VkPhysicalDeviceProperties vendorID, deviceID and pipelineCacheUUID.
This commit is contained in:
Bill Hollings 2018-02-21 14:26:04 -05:00 committed by GitHub
commit 88e355ff68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 145 additions and 34 deletions

View File

@ -131,8 +131,13 @@ the *Metal* environment.
2. Click the **+** button, and (selecting from the list of system libraries) add `libc++.tbd`.
3. If you do not have the **Link Frameworks Automatically** (aka `CLANG_MODULES_AUTOLINK`) and
**Enable Modules (C and Objective-C** (aka `CLANG_ENABLE_MODULES`) settings enabled, click the
**+** button, and (selecting from the list of system frameworks) add `Metal.framework`,
`IOSurface.framework`, and `QuartzCore.framework`.
**+** button, and (selecting from the list of system frameworks) add the following frameworks:
- `Metal.framework`
- `IOSurface.framework`
- `QuartzCore.framework`
- `IOKit.framework` (*macOS*)
- `UIKit.framework` (*iOS*)
- `Foundation.framework`.
4. When a *Metal* app is running from *Xcode*, the default ***Scheme*** settings reduce
performance. To improve performance and gain the benefits of *Metal*, perform the
@ -185,8 +190,13 @@ follow these instructions:
2. Click the **+** button, and (selecting from the list of system libraries) add `libc++.tbd`.
3. If you do not have the **Link Frameworks Automatically** (aka `CLANG_MODULES_AUTOLINK`) and
**Enable Modules (C and Objective-C** (aka `CLANG_ENABLE_MODULES`) settings enabled, click the
**+** button, and (selecting from the list of system frameworks) add `Metal.framework`,
`IOSurface.framework`, and `QuartzCore.framework`.
**+** button, and (selecting from the list of system frameworks) add the following frameworks:
- `Metal.framework`
- `IOSurface.framework`
- `QuartzCore.framework`
- `IOKit.framework` (*macOS*)
- `UIKit.framework` (*iOS*)
- `Foundation.framework`.
4. Arrange to install the `libMoltenVK.dylib` file in your application environment:

@ -1 +1 @@
Subproject commit 6a0f6980ef851c3973f8e723737aa764b04b18ca
Subproject commit 3925fe88e91e32747db84c2bd3caa5e1f3ec70c7

2
External/Vulkan-Hpp vendored

@ -1 +1 @@
Subproject commit 047961e987a7a42f45249c969b10d044f9396a8d
Subproject commit 82a14093cfb3f11da82d3b080ab650ce36a5ba13

@ -1 +1 @@
Subproject commit 54c674136a33dae33d378f734b174d7ec7ef633b
Subproject commit eb59198227debc125069ad9a008a1b17cefd564f

View File

@ -770,7 +770,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\nexport MVK_PROD_NAME=\"MoltenVK\"\nexport MVK_DYLIB_NAME=\"lib${MVK_PROD_NAME}.dylib\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nexport MVK_PLATFORM_SDK_DIR=\"${PLATFORM_DEVELOPER_SDK_DIR}/${PLATFORM_NAME}.sdk\"\nexport MVK_SYS_FWK_DIR=\"${MVK_PLATFORM_SDK_DIR}/System/Library/Frameworks\"\nexport MVK_USR_LIB_DIR=\"${MVK_PLATFORM_SDK_DIR}/usr/lib\"\n\nclang \\\n-dynamiclib \\\n-arch x86_64 \\\n-mmacosx-version-min=10.11 \\\n-compatibility_version 1.0.0 -current_version 1.0.0 \\\n-install_name \"@rpath/${MVK_DYLIB_NAME}\" \\\n-Wno-incompatible-sysroot \\\n-isysroot ${MVK_PLATFORM_SDK_DIR} \\\n-iframework ${MVK_SYS_FWK_DIR} \\\n-framework Metal -framework IOSurface -framework QuartzCore -framework Foundation \\\n--library-directory ${MVK_USR_LIB_DIR} \\\n-lSystem -lc++ \\\n-o \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \\\n-force_load \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}\"\n";
shellScript = "set -e\n\nexport MVK_PROD_NAME=\"MoltenVK\"\nexport MVK_DYLIB_NAME=\"lib${MVK_PROD_NAME}.dylib\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nexport MVK_PLATFORM_SDK_DIR=\"${PLATFORM_DEVELOPER_SDK_DIR}/${PLATFORM_NAME}.sdk\"\nexport MVK_SYS_FWK_DIR=\"${MVK_PLATFORM_SDK_DIR}/System/Library/Frameworks\"\nexport MVK_USR_LIB_DIR=\"${MVK_PLATFORM_SDK_DIR}/usr/lib\"\n\nclang \\\n-dynamiclib \\\n-arch x86_64 \\\n-mmacosx-version-min=10.11 \\\n-compatibility_version 1.0.0 -current_version 1.0.0 \\\n-install_name \"@rpath/${MVK_DYLIB_NAME}\" \\\n-Wno-incompatible-sysroot \\\n-isysroot ${MVK_PLATFORM_SDK_DIR} \\\n-iframework ${MVK_SYS_FWK_DIR} \\\n-framework Metal -framework IOSurface -framework IOKit -framework QuartzCore -framework Foundation \\\n--library-directory ${MVK_USR_LIB_DIR} \\\n-lSystem -lc++ \\\n-o \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \\\n-force_load \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}\"\n";
};
A9731FAD1EDDAE39006B7298 /* Create Dynamic Library */ = {
isa = PBXShellScriptBuildPhase;
@ -784,7 +784,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\nexport MVK_PROD_NAME=\"MoltenVK\"\nexport MVK_DYLIB_NAME=\"lib${MVK_PROD_NAME}.dylib\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nexport MVK_PLATFORM_SDK_DIR=\"${PLATFORM_DEVELOPER_SDK_DIR}/${PLATFORM_NAME}.sdk\"\nexport MVK_SYS_FWK_DIR=\"${MVK_PLATFORM_SDK_DIR}/System/Library/Frameworks\"\nexport MVK_USR_LIB_DIR=\"${MVK_PLATFORM_SDK_DIR}/usr/lib\"\n\nclang \\\n-dynamiclib \\\n-arch arm64 \\\n-mios-version-min=9.0 \\\n-compatibility_version 1.0.0 -current_version 1.0.0 \\\n-install_name \"@rpath/${MVK_DYLIB_NAME}\" \\\n-Wno-incompatible-sysroot \\\n-isysroot ${MVK_PLATFORM_SDK_DIR} \\\n-iframework ${MVK_SYS_FWK_DIR} \\\n-framework Metal -framework IOSurface -framework QuartzCore -framework Foundation \\\n--library-directory ${MVK_USR_LIB_DIR} \\\n-lSystem -lc++ \\\n-o \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \\\n-force_load \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}\"\n";
shellScript = "set -e\n\nexport MVK_PROD_NAME=\"MoltenVK\"\nexport MVK_DYLIB_NAME=\"lib${MVK_PROD_NAME}.dylib\"\nexport MVK_BUILT_PROD_PATH=\"${BUILT_PRODUCTS_DIR}\"\nexport MVK_PLATFORM_SDK_DIR=\"${PLATFORM_DEVELOPER_SDK_DIR}/${PLATFORM_NAME}.sdk\"\nexport MVK_SYS_FWK_DIR=\"${MVK_PLATFORM_SDK_DIR}/System/Library/Frameworks\"\nexport MVK_USR_LIB_DIR=\"${MVK_PLATFORM_SDK_DIR}/usr/lib\"\n\nclang \\\n-dynamiclib \\\n-arch arm64 \\\n-mios-version-min=9.0 \\\n-compatibility_version 1.0.0 -current_version 1.0.0 \\\n-install_name \"@rpath/${MVK_DYLIB_NAME}\" \\\n-Wno-incompatible-sysroot \\\n-isysroot ${MVK_PLATFORM_SDK_DIR} \\\n-iframework ${MVK_SYS_FWK_DIR} \\\n-framework Metal -framework IOSurface -framework UIKit -framework QuartzCore -framework Foundation \\\n--library-directory ${MVK_USR_LIB_DIR} \\\n-lSystem -lc++ \\\n-o \"${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}\" \\\n-force_load \"${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework/${MVK_PROD_NAME}\"\n";
};
/* End PBXShellScriptBuildPhase section */

View File

@ -288,16 +288,6 @@ VkResult MVKPhysicalDevice::getPhysicalDeviceMemoryProperties(VkPhysicalDeviceMe
#pragma mark Construction
/** Returns the device type of the specified MTLDevice. */
static VkPhysicalDeviceType getDeviceType(id<MTLDevice> mtlDevice) {
#if MVK_IOS
return VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
#endif
#if MVK_MACOS
return (mtlDevice.isLowPower ? VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU : VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
#endif
}
/** Initializes the Metal-specific physical device features of this instance. */
void MVKPhysicalDevice::initMetalFeatures() {
memset(&_metalFeatures, 0, sizeof(_metalFeatures)); // Start with everything cleared
@ -472,14 +462,10 @@ void MVKPhysicalDevice::initFeatures() {
void MVKPhysicalDevice::initProperties() {
memset(&_properties, 0, sizeof(_properties)); // Start with everything cleared
// TODO: determine correct values
_properties.apiVersion = MVK_VULKAN_API_VERSION;
_properties.driverVersion = MVK_VERSION;
_properties.vendorID = 0;
_properties.deviceID = 0;
_properties.deviceType = getDeviceType(_mtlDevice);
strlcpy(_properties.deviceName, _mtlDevice.name.UTF8String, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
memset(_properties.pipelineCacheUUID, 0, VK_UUID_SIZE);
mvkPopulateGPUInfo(_properties, _mtlDevice);
// Limits
#if MVK_IOS
@ -865,7 +851,7 @@ void MVKPhysicalDevice::initMemoryProperties() {
}
void MVKPhysicalDevice::logFeatureSets() {
string fsMsg = "GPU device %s supports the following Metal Feature Sets:";
string fsMsg = "GPU device %s (vendorID: %#06x, deviceID: %#06x, pipelineCacheUUID: %s) supports the following Metal Feature Sets:";
#if MVK_IOS
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1] ) { fsMsg += "\n\tiOS GPU Family 4 v1"; }
@ -891,7 +877,8 @@ void MVKPhysicalDevice::logFeatureSets() {
if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v1] ) { fsMsg += "\n\tOSX GPU Family 1 v1"; }
#endif
MVKLogInfo(fsMsg.c_str(), _properties.deviceName);
MVKLogInfo(fsMsg.c_str(), _properties.deviceName, _properties.vendorID, _properties.deviceID,
[[[NSUUID alloc] initWithUUIDBytes: _properties.pipelineCacheUUID] autorelease].UUIDString.UTF8String);
}
/** Initializes the queue families supported by this instance. */

View File

@ -29,13 +29,11 @@ const MVKMTLFunction MVKMTLFunctionNull = { nil, MTLSizeMake(1, 1, 1) };
#pragma mark -
#pragma mark MVKShaderLibrary
uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, uint32_t constantId)
static uint32_t getOffsetForConstantId(const VkSpecializationInfo* pSpecInfo, uint32_t constantId)
{
for (uint32_t specIdx = 0; specIdx < pSpecInfo->mapEntryCount; specIdx++) {
const VkSpecializationMapEntry* pMapEntry = &pSpecInfo->pMapEntries[specIdx];
if (pMapEntry->constantID == constantId) {
return pMapEntry->offset;
}
if (pMapEntry->constantID == constantId) { return pMapEntry->offset; }
}
return -1;

View File

@ -22,6 +22,7 @@
#pragma once
#include "MVKCommonEnvironment.h"
#include <vulkan/vulkan.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
@ -105,4 +106,6 @@ MVKOSVersion mvkOSVersion(void);
/** Returns an approximation of how much memory, in bytes, the device can use with good performance. */
uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice);
/** Populate the propertes with info about the GPU represented by the MTLDevice. */
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice);

View File

@ -20,9 +20,22 @@
#include "MVKOSExtensions.h"
#include "MVKFoundation.h"
#import <mach/mach.h>
#import <mach/mach_host.h>
#include <vector>
#include <mach/mach.h>
#include <mach/mach_host.h>
#include <uuid/uuid.h>
#if MVK_MACOS
#import <CoreFoundation/CFData.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/IOKitKeys.h>
#endif
#if MVK_IOS
#import <UIKit/UIDevice.h>
#endif
using namespace std;
static const MVKOSVersion kMVKOSVersionUnknown = 0.0f;
static MVKOSVersion _mvkOSVersion = kMVKOSVersionUnknown;
@ -131,4 +144,104 @@ uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice) {
return 128 * MEBI; // Conservative minimum for macOS GPU's & iOS shared memory
}
// Personalize the pipelineCacheUUID by blending in the vendorID and deviceID values into the lower 8 bytes.
static void mvkBlendUUID(VkPhysicalDeviceProperties& devProps) {
uint32_t idOffset = VK_UUID_SIZE;
idOffset -= sizeof(uint32_t);
*(uint32_t*)&devProps.pipelineCacheUUID[idOffset] ^= NSSwapHostIntToBig(devProps.deviceID);
idOffset -= sizeof(uint32_t);
*(uint32_t*)&devProps.pipelineCacheUUID[idOffset] ^= NSSwapHostIntToBig(devProps.vendorID);
}
#if MVK_MACOS
static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef propertyName) {
uint32_t value = 0;
CFTypeRef cfProp = IORegistryEntrySearchCFProperty(entry,
kIOServicePlane,
propertyName,
kCFAllocatorDefault,
kIORegistryIterateRecursively |
kIORegistryIterateParents);
if (cfProp) {
const uint32_t* pValue = reinterpret_cast<const uint32_t*>(CFDataGetBytePtr((CFDataRef)cfProp));
if (pValue) { value = *pValue; }
CFRelease(cfProp);
}
return value;
}
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice) {
static const UInt32 kIntelVendorId = 0x8086;
bool isFound = false;
bool isIntegrated = mtlDevice.isLowPower;
devProps.deviceType = isIntegrated ? VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU : VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
strlcpy(devProps.deviceName, mtlDevice.name.UTF8String, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
// Iterate all GPU's, looking for a match.
// The match dictionary is consumed by IOServiceGetMatchingServices and does not need to be released
io_iterator_t entryIterator;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceMatching("IOPCIDevice"),
&entryIterator) == kIOReturnSuccess) {
io_registry_entry_t entry;
while ( !isFound && (entry = IOIteratorNext(entryIterator)) ) {
if (mvkGetEntryProperty(entry, CFSTR("class-code")) == 0x30000) { // 0x30000 : DISPLAY_VGA
// The Intel GPU will always be marked as integrated.
// Return on a match of either Intel && low power, or non-Intel and non-low-power.
uint32_t vendorID = mvkGetEntryProperty(entry, CFSTR("vendor-id"));
if ( (vendorID == kIntelVendorId) == isIntegrated) {
isFound = true;
devProps.vendorID = vendorID;
devProps.deviceID = mvkGetEntryProperty(entry, CFSTR("device-id"));
}
}
}
IOObjectRelease(entryIterator);
}
// Create a pipelineCacheUUID by blending the UUID of the computer with the vendor and device ID's
uuid_t uuid = {};
timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
gethostuuid(uuid, &ts);
memcpy(devProps.pipelineCacheUUID, uuid, min(sizeof(uuid_t), (size_t)VK_UUID_SIZE));
mvkBlendUUID(devProps);
}
#endif //MVK_MACOS
#if MVK_IOS
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice) {
NSUInteger coreCnt = NSProcessInfo.processInfo.processorCount;
uint32_t devID = 0xa070;
if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1]) {
devID = 0xa110;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1]) {
devID = coreCnt > 2 ? 0xa101 : 0xa100;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1]) {
devID = coreCnt > 2 ? 0xa081 : 0xa080;
}
devProps.vendorID = 0x0000106b; // Apple's PCI ID
devProps.deviceID = devID;
devProps.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
strlcpy(devProps.deviceName, mtlDevice.name.UTF8String, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
// Create a pipelineCacheUUID by blending the UUID of the computer with the vendor and device ID's
uuid_t uuid = {};
[UIDevice.currentDevice.identifierForVendor getUUIDBytes:uuid];
memcpy(devProps.pipelineCacheUUID, uuid, min(sizeof(uuid_t), (size_t)VK_UUID_SIZE));
mvkBlendUUID(devProps);
}
#endif //MVK_IOS

View File

@ -135,7 +135,7 @@ Building **MoltenVK**
instructions in the [*Third-Party Components*](#third-party) section above to retrieve
and install the required third-party components.
>***Note:*** At runtime, **MoltenVK** can run on *iOS 9* and *macOS 11.0* devices,
>***Note:*** At runtime, **MoltenVK** can run on *iOS 9* and *macOS 10.11* devices,
>but it does reference advanced OS frameworks during building. *Xcode 9*
>or above is required to build **MoltenVK**, and build and link **MoltenVK** projects.