From 67743ab4235ba8ba27ea390068344a498d9d5c6f Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Fri, 10 May 2019 18:24:19 -0400 Subject: [PATCH] Automatically update VkPhysicalDeviceProperties::pipelineCacheUUID when SPIRV-Cross revision changes. Generate derived External/SPIRV-Cross/mvkSpirvCrossRevisionDerived.h header file from SPIRV-Cross_repo_revision file from within fetchDependencies. MoltenVK includes derived header file and extracts first part of revision hash for inclusion in pipelineCacheUUID. Update highest available MTLFeatureSets for use in pipelineCacheUUID. Suppress echoing of script directory changes in fetchDependencies. --- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 1 + MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 50 ++++++++++++++++------- fetchDependencies | 15 ++++--- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index aef11ea6..129e6eed 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -317,6 +317,7 @@ protected: std::vector& getQueueFamilies(); void initPipelineCacheUUID(); MTLFeatureSet getHighestMTLFeatureSet(); + uint64_t getSpirvCrossRevision(); bool getImageViewIsSupported(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo); void logGPUInfo(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 58fd374d..41358b90 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -1343,35 +1343,36 @@ void MVKPhysicalDevice::initProperties() { void MVKPhysicalDevice::initPipelineCacheUUID() { - size_t uuidSize = sizeof(_properties.pipelineCacheUUID); // Clear the UUID - memset(&_properties.pipelineCacheUUID, 0, uuidSize); + memset(&_properties.pipelineCacheUUID, 0, sizeof(_properties.pipelineCacheUUID)); - uint32_t uuidComponent; - size_t uuidComponentSize = sizeof(uint32_t); + size_t uuidComponentOffset = 0; - size_t uuidComponentOffset = uuidSize; - - // Lower 4 bytes contains MoltenVK version - uuidComponent = MVK_VERSION; - uuidComponentOffset -= uuidComponentSize; - *(uint32_t*)&_properties.pipelineCacheUUID[uuidComponentOffset] = NSSwapHostIntToBig(uuidComponent); + // First 4 bytes contains MoltenVK version + uint32_t mvkVersion = MVK_VERSION; + *(uint32_t*)&_properties.pipelineCacheUUID[uuidComponentOffset] = NSSwapHostIntToBig(mvkVersion); + uuidComponentOffset += sizeof(mvkVersion); // Next 4 bytes contains hightest Metal feature set supported by this device - uuidComponent = (uint32_t)getHighestMTLFeatureSet(); - uuidComponentOffset -= uuidComponentSize; - *(uint32_t*)&_properties.pipelineCacheUUID[uuidComponentOffset] = NSSwapHostIntToBig(uuidComponent); + uint32_t mtlFeatSet = (uint32_t)getHighestMTLFeatureSet(); + *(uint32_t*)&_properties.pipelineCacheUUID[uuidComponentOffset] = NSSwapHostIntToBig(mtlFeatSet); + uuidComponentOffset += sizeof(mtlFeatSet); + + // Last 8 bytes contain the first part of the SPIRV-Cross Git revision + uint64_t spvxRev = getSpirvCrossRevision(); + *(uint64_t*)&_properties.pipelineCacheUUID[uuidComponentOffset] = NSSwapHostLongLongToBig(spvxRev); + uuidComponentOffset += sizeof(spvxRev); } MTLFeatureSet MVKPhysicalDevice::getHighestMTLFeatureSet() { #if MVK_IOS - MTLFeatureSet maxFS = MTLFeatureSet_iOS_GPUFamily4_v1; + MTLFeatureSet maxFS = MTLFeatureSet_iOS_GPUFamily4_v2; MTLFeatureSet minFS = MTLFeatureSet_iOS_GPUFamily1_v1; #endif #if MVK_MACOS - MTLFeatureSet maxFS = MTLFeatureSet_macOS_GPUFamily1_v3; + MTLFeatureSet maxFS = MTLFeatureSet_macOS_GPUFamily2_v1; MTLFeatureSet minFS = MTLFeatureSet_macOS_GPUFamily1_v1; #endif @@ -1385,6 +1386,25 @@ MTLFeatureSet MVKPhysicalDevice::getHighestMTLFeatureSet() { return minFS; } +// Retrieve the SPIRV-Cross Git revision hash from a derived header file that was created in the fetchDependencies script. +uint64_t MVKPhysicalDevice::getSpirvCrossRevision() { + +#include "../External/SPIRV-Cross/mvkSpirvCrossRevisionDerived.h" + + static const string revStr(spirvCrossRevisionString, 0, 16); // We just need the first 16 chars + static const string lut("0123456789ABCDEF"); + + uint64_t revVal = 0; + for (char c : revStr) { + size_t cVal = lut.find(toupper(c)); + if (cVal != string::npos) { + revVal <<= 4; + revVal += cVal; + } + } + return revVal; +} + /** Initializes the memory properties of this instance. */ void MVKPhysicalDevice::initMemoryProperties() { diff --git a/fetchDependencies b/fetchDependencies index 6526b4b5..92e2ec6a 100755 --- a/fetchDependencies +++ b/fetchDependencies @@ -80,13 +80,13 @@ update_repo() { cd $1 git fetch --all git checkout --force $3 - cd - + cd - > /dev/null else rm -rf $1 git clone $2 $1 cd $1 git checkout $3 - cd - + cd - > /dev/null fi } @@ -105,7 +105,7 @@ build_repo() { make -j $(sysctl -n hw.activecpu) fi - cd - + cd - > /dev/null } @@ -189,6 +189,11 @@ else update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV} fi +# Record the SPIRV-Cross revision as a derived header file suitable for including in a build +HDR_FILE=${REPO_NAME}/mvkSpirvCrossRevisionDerived.h +echo "// Auto-generated by MoltenVK" > ${HDR_FILE} +echo "static const char* spirvCrossRevisionString = \"${REPO_REV}\";" >> ${HDR_FILE} + # ----------------- glslang ------------------- @@ -212,7 +217,7 @@ else cd ${REPO_NAME} ./update_glslang_sources.py - cd - + cd - > /dev/null fi #Make sure the embedded spirv-tools is built @@ -248,7 +253,7 @@ update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV} cd "${REPO_NAME}/Sample-Programs/Hologram" ./generate-dispatch-table HelpersDispatchTable.h ./generate-dispatch-table HelpersDispatchTable.cpp -cd - +cd - > /dev/null # ----------------- Cleanup -------------------