From 0ac1edbac0d71fd5da9dcd680993b6d5fa9a33f7 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Fri, 22 Mar 2019 19:36:21 -0400 Subject: [PATCH] Project build enhancements, and MoltenVKShaderConverter tool now validates converted MSL with a test compilation. Project build scripts now build dylib and framework in separate build directories to enable MoltenVKShaderConverter to link to static library instead of dynamic library. Final Package structure remains the same. In Debug build, copy dylib dSYM files to Package. Package/Latest directory now links relative to local Debug or Release directory. Add install option to Makefile. MoltenVKShaderConverter tool now validates converted MSL with a test compilation. Clean up various MSL conversion and compilation error logging. MVKCommandResourceFactory wrap Metal library compile with autorelease pool. Build ExternalDependencies with same symbol hiding as MoltenVK to suppress visibility warnings. Update What's New document. --- Docs/Whats_New.md | 5 ++- .../project.pbxproj | 4 ++ Makefile | 5 +++ .../Commands/MVKCommandResourceFactory.mm | 39 ++++++++++--------- .../MoltenVK/GPUObjects/MVKShaderModule.mm | 7 ++-- MoltenVK/MoltenVK/GPUObjects/MVKSync.mm | 5 ++- MoltenVK/MoltenVK/Utility/MVKWatermark.mm | 6 +-- .../GLSLConversion.mm | 4 +- .../SPIRVConversion.mm | 4 +- .../project.pbxproj | 16 +++++--- .../MoltenVKShaderConverterTool.cpp | 23 ++++++++--- .../{DirectorySupport.h => OSSupport.h} | 10 ++++- .../{DirectorySupport.mm => OSSupport.mm} | 16 +++++++- README.md | 9 ++++- Scripts/create_dylib.sh | 8 +++- Scripts/create_framework.sh | 4 +- Scripts/package_moltenvk.sh | 10 ++++- Scripts/package_shader_converter_lib.sh | 10 ++++- Scripts/package_update_latest.sh | 2 +- 19 files changed, 130 insertions(+), 57 deletions(-) rename MoltenVKShaderConverter/MoltenVKShaderConverterTool/{DirectorySupport.h => OSSupport.h} (81%) rename MoltenVKShaderConverter/MoltenVKShaderConverterTool/{DirectorySupport.mm => OSSupport.mm} (79%) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 8c4edca2..3d0b6293 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -26,10 +26,13 @@ Released TBD - Fix conditions when multiple functions return VK_INCOMPLETE. - Fix potential memory leak on synchronous command buffer submission. - Increase shader float constant accuracy beyond 6 digits of precision. -- MoltenVKShaderConverterTool support cs & csh for compute shader file extensions. +- MoltenVKShaderConverter tool support cs & csh for compute shader file extensions. +- MoltenVKShaderConverter tool validates converted MSL with a test compilation. - `fetchDependencies`: Stop on first error. - Fix a possible race condition around MVKMTLBufferAllocation. - Fix memory overrun if no vertex buffer found with same binding as a vertex attribute. +- Debug build mode includes `dSYM` file for each `dylib` file. +- `Makefile` supports `install` target to install `MoltenVK.framework` into `/Library/Frameworks/`. - Update to latest SPIRV-Cross version: - MSL: Add support for Metal 2 indirect argument buffers. - MSL: Add support for tessellation control & evaluation shaders. diff --git a/ExternalDependencies.xcodeproj/project.pbxproj b/ExternalDependencies.xcodeproj/project.pbxproj index d6046545..03950733 100644 --- a/ExternalDependencies.xcodeproj/project.pbxproj +++ b/ExternalDependencies.xcodeproj/project.pbxproj @@ -3729,9 +3729,11 @@ COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; @@ -3775,8 +3777,10 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = fast; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; diff --git a/Makefile b/Makefile index 7ae5e03b..fec26424 100644 --- a/Makefile +++ b/Makefile @@ -18,3 +18,8 @@ clean: xcodebuild -quiet -project "$(XCODE_PROJ)" -scheme "$(XCODE_SCHEME_BASE)" clean rm -rf Package +#Likely requires 'sudo make install' +.PHONY: install +install: + /bin/cp -a Package/Latest/MoltenVK/macOS/framework/MoltenVK.framework /Library/Frameworks/ + diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandResourceFactory.mm b/MoltenVK/MoltenVK/Commands/MVKCommandResourceFactory.mm index a2ba2620..fad8ff66 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandResourceFactory.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandResourceFactory.mm @@ -406,21 +406,25 @@ id MVKCommandResourceFactory::getFunctionNamed(const char* funcName } id MVKCommandResourceFactory::newMTLFunction(NSString* mslSrcCode, NSString* funcName) { - uint64_t startTime = _device->getPerformanceTimestamp(); - NSError* err = nil; - id mtlLib = [[getMTLDevice() newLibraryWithSource: mslSrcCode - options: getDevice()->getMTLCompileOptions() - error: &err] autorelease]; - _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.mslCompile, startTime); - if (err) { - mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Could not compile support shader from MSL source:\n%s\n %s (code %li) %s", mslSrcCode.UTF8String, err.localizedDescription.UTF8String, (long)err.code, err.localizedFailureReason.UTF8String); - return nil; - } + @autoreleasepool { + NSError* err = nil; + uint64_t startTime = _device->getPerformanceTimestamp(); + id mtlLib = [[getMTLDevice() newLibraryWithSource: mslSrcCode + options: getDevice()->getMTLCompileOptions() + error: &err] autorelease]; + _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.mslCompile, startTime); + if (err) { + mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, + "Could not compile support shader from MSL source (Error code %li):\n%s\n%s", + (long)err.code, mslSrcCode.UTF8String, err.localizedDescription.UTF8String); + return nil; + } - startTime = _device->getPerformanceTimestamp(); - id mtlFunc = [mtlLib newFunctionWithName: funcName]; - _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.functionRetrieval, startTime); - return mtlFunc; + startTime = _device->getPerformanceTimestamp(); + id mtlFunc = [mtlLib newFunctionWithName: funcName]; + _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.functionRetrieval, startTime); + return mtlFunc; + } } id MVKCommandResourceFactory::newMTLRenderPipelineState(MTLRenderPipelineDescriptor* plDesc) { @@ -447,16 +451,15 @@ MVKCommandResourceFactory::MVKCommandResourceFactory(MVKDevice* device) : MVKBas // Initializes the Metal shaders used for command activity. void MVKCommandResourceFactory::initMTLLibrary() { - uint64_t startTime = _device->getPerformanceTimestamp(); @autoreleasepool { NSError* err = nil; + uint64_t startTime = _device->getPerformanceTimestamp(); _mtlLibrary = [getMTLDevice() newLibraryWithSource: _MVKStaticCmdShaderSource options: getDevice()->getMTLCompileOptions() error: &err]; // retained - MVKAssert( !err, "Could not compile command shaders (code %li):\n%s\n%s", - (long)err.code, err.localizedDescription.UTF8String, err.localizedFailureReason.UTF8String); + MVKAssert( !err, "Could not compile command shaders (Error code %li):\n%s", (long)err.code, err.localizedDescription.UTF8String); + _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.mslCompile, startTime); } - _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.mslCompile, startTime); } // Initializes the empty device memory used to back temporary VkImages. diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm index 23fcc53d..46b5cecd 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.mm @@ -146,11 +146,10 @@ void MVKShaderLibrary::handleCompilationError(NSError* err, const char* opDesc) if ( !err ) return; if (_mtlLibrary) { - MVKLogInfo("%s succeeded with warnings (code %li):\n\n%s", opDesc, (long)err.code, - err.localizedDescription.UTF8String); + MVKLogInfo("%s succeeded with warnings (Error code %li):\n%s", opDesc, (long)err.code, err.localizedDescription.UTF8String); } else { setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, - "%s failed (code %li):\n\n%s", + "%s failed (Error code %li):\n%s", opDesc, (long)err.code, err.localizedDescription.UTF8String)); } @@ -351,7 +350,7 @@ id MVKShaderLibraryCompiler::newMTLLibrary(NSString* mslSourceCode) void MVKShaderLibraryCompiler::handleError() { if (_mtlLibrary) { - MVKLogInfo("%s compilation succeeded with warnings (code %li):\n\n%s", _compilerType.c_str(), + MVKLogInfo("%s compilation succeeded with warnings (Error code %li):\n%s", _compilerType.c_str(), (long)_compileError.code, _compileError.localizedDescription.UTF8String); } else { MVKMetalCompiler::handleError(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm index 8f39de2c..1d198036 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm @@ -194,7 +194,10 @@ void MVKMetalCompiler::compile(unique_lock& lock, dispatch_block_t block) } void MVKMetalCompiler::handleError() { - setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "%s compile failed (error code %li):\n%s.", _compilerType.c_str(), (long)_compileError.code, _compileError.localizedDescription.UTF8String)); + setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, + "%s compile failed (Error code %li):\n%s.", + _compilerType.c_str(), (long)_compileError.code, + _compileError.localizedDescription.UTF8String)); } // Returns whether the compilation came in late, after the compiler was destroyed. diff --git a/MoltenVK/MoltenVK/Utility/MVKWatermark.mm b/MoltenVK/MoltenVK/Utility/MVKWatermark.mm index 71eb7557..a87897a7 100644 --- a/MoltenVK/MoltenVK/Utility/MVKWatermark.mm +++ b/MoltenVK/MoltenVK/Utility/MVKWatermark.mm @@ -126,8 +126,7 @@ id MVKWatermark::newRenderPipelineState() { NSError* err = nil; id rps = [_mtlDevice newRenderPipelineStateWithDescriptor: plDesc error: &err]; // retained - MVKAssert( !err, "Could not create watermark pipeline state %s (code %li) %s", - err.localizedDescription.UTF8String, (long)err.code, err.localizedFailureReason.UTF8String); + MVKAssert( !err, "Could not create watermark pipeline state (Error code %li)\n%s", (long)err.code, err.localizedDescription.UTF8String); return rps; } @@ -307,8 +306,7 @@ void MVKWatermark::initShaders(const char* mslSourceCode) { id mtlLib = [[_mtlDevice newLibraryWithSource: @(mslSourceCode) options: nil error: &err] autorelease]; - MVKAssert( !err, "Could not compile watermark shaders %s (code %li) %s", - err.localizedDescription.UTF8String, (long)err.code, err.localizedFailureReason.UTF8String); + MVKAssert( !err, "Could not compile watermark shaders (Error code %li):\n%s", (long)err.code, err.localizedDescription.UTF8String); _mtlFunctionVertex = [mtlLib newFunctionWithName: @"watermarkVertex"]; // retained _mtlFunctionFragment = [mtlLib newFunctionWithName: @"watermarkFragment"]; // retained diff --git a/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLConversion.mm b/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLConversion.mm index 4bfb6cc4..8cfb49b7 100644 --- a/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLConversion.mm +++ b/MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/GLSLConversion.mm @@ -75,8 +75,8 @@ MVK_PUBLIC_SYMBOL bool mvkConvertGLSLFileToSPIRV(const char* glslFilepath, error: &err]; if (err) { if (pResultLog) { - NSString* errMsg = [NSString stringWithFormat: @"Unable to convert GLSL in file %@ to SPIR-V: %@ (code %li) %@", - filePath, err.localizedDescription, (long)err.code, err.localizedFailureReason]; + NSString* errMsg = [NSString stringWithFormat: @"Unable to convert GLSL in file %@ to SPIR-V (Error code %li):\n%@", + filePath, (long)err.code, err.localizedDescription]; *pResultLog = (char*)malloc(errMsg.length + 1); strcpy(*pResultLog, errMsg.UTF8String); } diff --git a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVConversion.mm b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVConversion.mm index a37c4000..1b8af9b4 100644 --- a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVConversion.mm +++ b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVConversion.mm @@ -64,8 +64,8 @@ MVK_PUBLIC_SYMBOL bool mvkConvertSPIRVFileToMSL(const char* spvFilepath, NSData* spv = [NSData dataWithContentsOfFile: filePath options: 0 error: &err]; if (err) { if (pResultLog) { - NSString* errMsg = [NSString stringWithFormat: @"Unable to convert SPIR-V in file %@ to MSL: %@ (code %li) %@", - filePath, err.localizedDescription, (long)err.code, err.localizedFailureReason]; + NSString* errMsg = [NSString stringWithFormat: @"Unable to convert SPIR-V in file %@ to MSL (Error code %li):\n%@", + filePath, (long)err.code, err.localizedDescription]; *pResultLog = (char*)malloc(errMsg.length + 1); strcpy(*pResultLog, errMsg.UTF8String); } diff --git a/MoltenVKShaderConverter/MoltenVKShaderConverter.xcodeproj/project.pbxproj b/MoltenVKShaderConverter/MoltenVKShaderConverter.xcodeproj/project.pbxproj index e34da461..4cccc865 100644 --- a/MoltenVKShaderConverter/MoltenVKShaderConverter.xcodeproj/project.pbxproj +++ b/MoltenVKShaderConverter/MoltenVKShaderConverter.xcodeproj/project.pbxproj @@ -31,7 +31,7 @@ A928C91C1D0488DC00071B88 /* SPIRVConversion.mm in Sources */ = {isa = PBXBuildFile; fileRef = A928C9181D0488DC00071B88 /* SPIRVConversion.mm */; }; A95096BB2003D00300F10950 /* FileSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = A925B70A1C7754B2006E7ECD /* FileSupport.mm */; }; A95096BC2003D00300F10950 /* FileSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = A925B70A1C7754B2006E7ECD /* FileSupport.mm */; }; - A95096BF2003D32400F10950 /* DirectorySupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = A95096BD2003D32400F10950 /* DirectorySupport.mm */; }; + A95096BF2003D32400F10950 /* OSSupport.mm in Sources */ = {isa = PBXBuildFile; fileRef = A95096BD2003D32400F10950 /* OSSupport.mm */; }; A972AD2B21CEE6A90013AB25 /* libglslang.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A972AD2A21CEE6A90013AB25 /* libglslang.a */; }; A972AD3121CEE7040013AB25 /* libSPIRVCross.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A972AD2F21CEE7040013AB25 /* libSPIRVCross.a */; }; A972AD3221CEE7040013AB25 /* libSPIRVTools.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A972AD3021CEE7040013AB25 /* libSPIRVTools.a */; }; @@ -44,6 +44,7 @@ A98149671FB6A98A005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149651FB6A98A005F00B4 /* MVKStrings.h */; }; A98149681FB6A98A005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149651FB6A98A005F00B4 /* MVKStrings.h */; }; A98149691FB6A98A005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149651FB6A98A005F00B4 /* MVKStrings.h */; }; + A9A14E332244388700C080F3 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9A14E322244388700C080F3 /* Metal.framework */; }; A9C70F5A221B2F6500FBA31A /* libSPIRVTools.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A972AD3021CEE7040013AB25 /* libSPIRVTools.a */; }; A9C70F5B221B2F8100FBA31A /* libSPIRVTools.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A972AD3421CEE7330013AB25 /* libSPIRVTools.a */; }; A9C70F5F221B321700FBA31A /* SPIRVSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A9C70F5D221B321600FBA31A /* SPIRVSupport.h */; }; @@ -98,8 +99,8 @@ A928C9181D0488DC00071B88 /* SPIRVConversion.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SPIRVConversion.mm; sourceTree = ""; }; A93903BF1C57E9D700FE90DC /* libMoltenVKSPIRVToMSLConverter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVKSPIRVToMSLConverter.a; sourceTree = BUILT_PRODUCTS_DIR; }; A93903C71C57E9ED00FE90DC /* libMoltenVKSPIRVToMSLConverter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVKSPIRVToMSLConverter.a; sourceTree = BUILT_PRODUCTS_DIR; }; - A95096BD2003D32400F10950 /* DirectorySupport.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DirectorySupport.mm; sourceTree = ""; }; - A95096BE2003D32400F10950 /* DirectorySupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectorySupport.h; sourceTree = ""; }; + A95096BD2003D32400F10950 /* OSSupport.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSSupport.mm; sourceTree = ""; }; + A95096BE2003D32400F10950 /* OSSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSSupport.h; sourceTree = ""; }; A964BD5F1C57EFBD00D930D8 /* MoltenVKShaderConverter */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MoltenVKShaderConverter; sourceTree = BUILT_PRODUCTS_DIR; }; A964BD601C57EFBD00D930D8 /* libMoltenVKGLSLToSPIRVConverter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVKGLSLToSPIRVConverter.a; sourceTree = BUILT_PRODUCTS_DIR; }; A964BD611C57EFBD00D930D8 /* libMoltenVKGLSLToSPIRVConverter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVKGLSLToSPIRVConverter.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -113,6 +114,7 @@ A97CC73E1C7527F3004A5C7E /* MoltenVKShaderConverterTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MoltenVKShaderConverterTool.cpp; sourceTree = ""; }; A97CC73F1C7527F3004A5C7E /* MoltenVKShaderConverterTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoltenVKShaderConverterTool.h; sourceTree = ""; }; A98149651FB6A98A005F00B4 /* MVKStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKStrings.h; sourceTree = ""; }; + A9A14E322244388700C080F3 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; A9C70F5D221B321600FBA31A /* SPIRVSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SPIRVSupport.h; path = Common/SPIRVSupport.h; sourceTree = SOURCE_ROOT; }; A9C70F5E221B321700FBA31A /* SPIRVSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SPIRVSupport.cpp; path = Common/SPIRVSupport.cpp; sourceTree = SOURCE_ROOT; }; A9E337B7220129ED00363D2A /* MVKLogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKLogging.cpp; sourceTree = ""; }; @@ -125,6 +127,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A9A14E332244388700C080F3 /* Metal.framework in Frameworks */, A925B71A1C78DEB2006E7ECD /* libMoltenVKGLSLToSPIRVConverter.a in Frameworks */, A925B71B1C78DEB2006E7ECD /* libMoltenVKSPIRVToMSLConverter.a in Frameworks */, ); @@ -210,6 +213,7 @@ A972AD2921CEE6A80013AB25 /* Frameworks */ = { isa = PBXGroup; children = ( + A9A14E322244388700C080F3 /* Metal.framework */, A972AD2A21CEE6A90013AB25 /* libglslang.a */, A972AD3821CEE7480013AB25 /* libglslang.a */, A972AD2F21CEE7040013AB25 /* libSPIRVCross.a */, @@ -224,8 +228,8 @@ A97CC73C1C7527F3004A5C7E /* MoltenVKShaderConverterTool */ = { isa = PBXGroup; children = ( - A95096BE2003D32400F10950 /* DirectorySupport.h */, - A95096BD2003D32400F10950 /* DirectorySupport.mm */, + A95096BE2003D32400F10950 /* OSSupport.h */, + A95096BD2003D32400F10950 /* OSSupport.mm */, A97CC73D1C7527F3004A5C7E /* main.cpp */, A97CC73E1C7527F3004A5C7E /* MoltenVKShaderConverterTool.cpp */, A97CC73F1C7527F3004A5C7E /* MoltenVKShaderConverterTool.h */, @@ -618,7 +622,7 @@ A9E337B8220129ED00363D2A /* MVKLogging.cpp in Sources */, A97CC7411C7527F3004A5C7E /* MoltenVKShaderConverterTool.cpp in Sources */, A9C70F63221B321700FBA31A /* SPIRVSupport.cpp in Sources */, - A95096BF2003D32400F10950 /* DirectorySupport.mm in Sources */, + A95096BF2003D32400F10950 /* OSSupport.mm in Sources */, A97CC7401C7527F3004A5C7E /* main.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/MoltenVKShaderConverter/MoltenVKShaderConverterTool/MoltenVKShaderConverterTool.cpp b/MoltenVKShaderConverter/MoltenVKShaderConverterTool/MoltenVKShaderConverterTool.cpp index fd757083..31be593b 100644 --- a/MoltenVKShaderConverter/MoltenVKShaderConverterTool/MoltenVKShaderConverterTool.cpp +++ b/MoltenVKShaderConverter/MoltenVKShaderConverterTool/MoltenVKShaderConverterTool.cpp @@ -18,7 +18,7 @@ #include "MoltenVKShaderConverterTool.h" #include "FileSupport.h" -#include "DirectorySupport.h" +#include "OSSupport.h" #include "GLSLToSPIRVConverter.h" #include "SPIRVToMSLConverter.h" #include "SPIRVSupport.h" @@ -201,16 +201,27 @@ bool MoltenVKShaderConverterTool::convertSPIRV(const vector& spv, string path = mslOutFile; if (mslOutFile.empty()) { path = pathWithExtension(inFile, "metal", _shouldIncludeOrigPathExtn, _origPathExtnSep); } const string& msl = spvConverter.getMSL(); + + string compileErrMsg; + bool wasCompiled = compile(msl, compileErrMsg); + if (compileErrMsg.size() > 0) { + string preamble = wasCompiled ? "is valid but the validation compilation produced warnings " : "failed a validation compilation "; + compileErrMsg = "Generated MSL " + preamble + compileErrMsg; + log(compileErrMsg.c_str()); + } else { + log("Generated MSL was validated by a successful compilation with no warnings."); + } + vector fileContents; fileContents.insert(fileContents.end(), msl.begin(), msl.end()); - string errMsg; - if (writeFile(path, fileContents, errMsg)) { + string writeErrMsg; + if (writeFile(path, fileContents, writeErrMsg)) { string logMsg = "Saved MSL to file: " + lastPathComponent(path); - log(logMsg.data()); + log(logMsg.c_str()); return true; } else { - errMsg = "Could not write MSL file. " + errMsg; - log(errMsg.data()); + writeErrMsg = "Could not write MSL file. " + writeErrMsg; + log(writeErrMsg.c_str()); return false; } } diff --git a/MoltenVKShaderConverter/MoltenVKShaderConverterTool/DirectorySupport.h b/MoltenVKShaderConverter/MoltenVKShaderConverterTool/OSSupport.h similarity index 81% rename from MoltenVKShaderConverter/MoltenVKShaderConverterTool/DirectorySupport.h rename to MoltenVKShaderConverter/MoltenVKShaderConverterTool/OSSupport.h index eb7cb1bd..2f27f32f 100644 --- a/MoltenVKShaderConverter/MoltenVKShaderConverterTool/DirectorySupport.h +++ b/MoltenVKShaderConverter/MoltenVKShaderConverterTool/OSSupport.h @@ -1,5 +1,5 @@ /* - * DirectorySupport.h + * OSSupport.h * * Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com) * @@ -42,4 +42,12 @@ namespace mvk { bool isRecursive, std::string& errMsg); + /** + * Attempts to compile the MSL source code and returns whether it was successful. + * + * If unsuccessful, the return value will be false and the errMsg will contain an + * error message. Otherwise the return value will be true and the errMsg will be empty. + */ + bool compile(const std::string& mslSourceCode, std::string& errMsg); + } diff --git a/MoltenVKShaderConverter/MoltenVKShaderConverterTool/DirectorySupport.mm b/MoltenVKShaderConverter/MoltenVKShaderConverterTool/OSSupport.mm similarity index 79% rename from MoltenVKShaderConverter/MoltenVKShaderConverterTool/DirectorySupport.mm rename to MoltenVKShaderConverter/MoltenVKShaderConverterTool/OSSupport.mm index a3aff3ba..aae8edf7 100644 --- a/MoltenVKShaderConverter/MoltenVKShaderConverterTool/DirectorySupport.mm +++ b/MoltenVKShaderConverter/MoltenVKShaderConverterTool/OSSupport.mm @@ -1,5 +1,5 @@ /* - * DirectorySupport.mm + * OSSupport.mm * * Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com) * @@ -16,11 +16,12 @@ * limitations under the License. */ -#include "DirectorySupport.h" +#include "OSSupport.h" #include "FileSupport.h" #include "MoltenVKShaderConverterTool.h" #import +#import using namespace std; using namespace mvk; @@ -60,3 +61,14 @@ template bool mvk::iterateDirectory(const string& d bool isRecursive, string& errMsg); +bool mvk::compile(const string& mslSourceCode, string& errMsg) { + @autoreleasepool { + NSError* err = nil; + id mtlLib = [[MTLCreateSystemDefaultDevice() newLibraryWithSource: @(mslSourceCode.c_str()) + options: [[MTLCompileOptions new] autorelease] + error: &err] autorelease]; + errMsg = err ? [NSString stringWithFormat: @"(Error code %li):\n%@", (long)err.code, err.localizedDescription].UTF8String + : ""; + return !!mtlLib; + } +} diff --git a/README.md b/README.md index ce938750..dbc082b6 100644 --- a/README.md +++ b/README.md @@ -181,10 +181,15 @@ in the **_Release_** configuration from the command line. The following `make` t make macos make ios make clean + make install -The `make` targets above all require that *Xcode* is installed on your system. +The `install` target will copy the most recently built *macOS* `MoltenVK.framework` into +the `/Library/Frameworks` folder of your computer. Since `/Library/Frameworks` is protected, +you will generally need to run it as `sudo make install` and enter your password. -The default `make` command with no arguments is the same as `make all`. +The default `make` command with no arguments is the same as `make all`. + +The `make` targets all require that *Xcode* is installed on your system. Building from the command line creates the same `Package` folder structure described above when building from within *Xcode*. diff --git a/Scripts/create_dylib.sh b/Scripts/create_dylib.sh index 09f5bbaf..df223ff0 100755 --- a/Scripts/create_dylib.sh +++ b/Scripts/create_dylib.sh @@ -6,6 +6,8 @@ export MVK_DYLIB_NAME="lib${PRODUCT_NAME}.dylib" export MVK_SYS_FWK_DIR="${SDK_DIR}/System/Library/Frameworks" export MVK_USR_LIB_DIR="${SDK_DIR}/usr/lib" +mkdir -p "${BUILT_PRODUCTS_DIR}/dynamic" + if test x"${ENABLE_BITCODE}" = xYES; then MVK_EMBED_BITCODE="-fembed-bitcode" fi @@ -30,9 +32,11 @@ ${MVK_SAN} \ -iframework ${MVK_SYS_FWK_DIR} \ -framework Metal ${MVK_IOSURFACE_FWK} -framework ${MVK_UX_FWK} -framework QuartzCore -framework IOKit -framework Foundation \ --library-directory ${MVK_USR_LIB_DIR} \ --o "${BUILT_PRODUCTS_DIR}/${MVK_DYLIB_NAME}" \ +-o "${BUILT_PRODUCTS_DIR}/dynamic/${MVK_DYLIB_NAME}" \ -force_load "${BUILT_PRODUCTS_DIR}/lib${PRODUCT_NAME}.a" if test "$CONFIGURATION" = Debug; then - dsymutil "${BUILT_PRODUCTS_DIR}/${MVK_DYLIB_NAME}" -o "${DWARF_DSYM_FOLDER_PATH}/${MVK_DYLIB_NAME}.dSYM" + mkdir -p "${DWARF_DSYM_FOLDER_PATH}/dynamic" + dsymutil "${BUILT_PRODUCTS_DIR}/dynamic/${MVK_DYLIB_NAME}" \ + -o "${DWARF_DSYM_FOLDER_PATH}/dynamic/${MVK_DYLIB_NAME}.dSYM" fi diff --git a/Scripts/create_framework.sh b/Scripts/create_framework.sh index 7c5e5334..c4f1d3fe 100755 --- a/Scripts/create_framework.sh +++ b/Scripts/create_framework.sh @@ -3,9 +3,11 @@ set -e export MVK_TMPLT_PATH="${PROJECT_DIR}/../Templates/framework/${MVK_OS}" -export MVK_BUILT_FRWK_PATH="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework" +export MVK_BUILT_FRWK_PATH="${BUILT_PRODUCTS_DIR}/framework/${PRODUCT_NAME}.framework" export MVK_BUILT_FRWK_CONTENT_PATH="${MVK_BUILT_FRWK_PATH}/${MVK_FRWK_SUBPATH}" +mkdir -p "${BUILT_PRODUCTS_DIR}/framework" + rm -rf "${MVK_BUILT_FRWK_PATH}" cp -a "${MVK_TMPLT_PATH}/Template.framework" "${MVK_BUILT_FRWK_PATH}" cp -a "${BUILT_PRODUCTS_DIR}/lib${PRODUCT_NAME}.a" "${MVK_BUILT_FRWK_CONTENT_PATH}${PRODUCT_NAME}" diff --git a/Scripts/package_moltenvk.sh b/Scripts/package_moltenvk.sh index f76b31c4..850bde2a 100755 --- a/Scripts/package_moltenvk.sh +++ b/Scripts/package_moltenvk.sh @@ -8,13 +8,19 @@ export MVK_PKG_PROD_PATH="${PROJECT_DIR}/Package/${CONFIGURATION}/${MVK_PROD_NAM export MVK_PKG_PROD_PATH_OS="${MVK_PKG_PROD_PATH}/${MVK_OS}" rm -rf "${MVK_PKG_PROD_PATH_OS}" + mkdir -p "${MVK_PKG_PROD_PATH_OS}/static" cp -a "${MVK_BUILT_PROD_PATH}/lib${MVK_PROD_NAME}.a" "${MVK_PKG_PROD_PATH_OS}/static" + mkdir -p "${MVK_PKG_PROD_PATH_OS}/dynamic" -cp -a "${MVK_BUILT_PROD_PATH}/lib${MVK_PROD_NAME}.dylib" "${MVK_PKG_PROD_PATH_OS}/dynamic" +cp -a "${MVK_BUILT_PROD_PATH}/dynamic/lib${MVK_PROD_NAME}.dylib" "${MVK_PKG_PROD_PATH_OS}/dynamic" +if test "$CONFIGURATION" = Debug; then + cp -a "${DWARF_DSYM_FOLDER_PATH}/dynamic/lib${MVK_PROD_NAME}.dylib.dSYM" "${MVK_PKG_PROD_PATH_OS}/dynamic" +fi cp -a "${MVK_PROD_PROJ_PATH}/icd/${MVK_PROD_NAME}_icd.json" "${MVK_PKG_PROD_PATH_OS}/dynamic" + mkdir -p "${MVK_PKG_PROD_PATH_OS}/framework" -cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_PKG_PROD_PATH_OS}/framework" +cp -a "${MVK_BUILT_PROD_PATH}/framework/${MVK_PROD_NAME}.framework" "${MVK_PKG_PROD_PATH_OS}/framework" # Remove the code signature rm -rf "${MVK_PKG_PROD_PATH_OS}/framework/${MVK_PROD_NAME}.framework/_CodeSignature" diff --git a/Scripts/package_shader_converter_lib.sh b/Scripts/package_shader_converter_lib.sh index 7763d022..71bce460 100755 --- a/Scripts/package_shader_converter_lib.sh +++ b/Scripts/package_shader_converter_lib.sh @@ -7,9 +7,15 @@ export MVK_PKG_PROD_PATH="${MVK_PKG_BASE_PATH}/${MVK_PROD_NAME}" export MVK_PKG_PROD_PATH_OS="${MVK_PKG_PROD_PATH}/${MVK_OS}" rm -rf "${MVK_PKG_PROD_PATH_OS}" + mkdir -p "${MVK_PKG_PROD_PATH_OS}/static" cp -a "${MVK_BUILT_PROD_PATH}/lib${MVK_PROD_NAME}.a" "${MVK_PKG_PROD_PATH_OS}/static" + mkdir -p "${MVK_PKG_PROD_PATH_OS}/dynamic" -cp -a "${MVK_BUILT_PROD_PATH}/lib${MVK_PROD_NAME}.dylib" "${MVK_PKG_PROD_PATH_OS}/dynamic" +cp -a "${MVK_BUILT_PROD_PATH}/dynamic/lib${MVK_PROD_NAME}.dylib" "${MVK_PKG_PROD_PATH_OS}/dynamic" +if test "$CONFIGURATION" = Debug; then + cp -a "${DWARF_DSYM_FOLDER_PATH}/dynamic/lib${MVK_PROD_NAME}.dylib.dSYM" "${MVK_PKG_PROD_PATH_OS}/dynamic" +fi + mkdir -p "${MVK_PKG_PROD_PATH_OS}/framework" -cp -a "${MVK_BUILT_PROD_PATH}/${MVK_PROD_NAME}.framework" "${MVK_PKG_PROD_PATH_OS}/framework" +cp -a "${MVK_BUILT_PROD_PATH}/framework/${MVK_PROD_NAME}.framework" "${MVK_PKG_PROD_PATH_OS}/framework" diff --git a/Scripts/package_update_latest.sh b/Scripts/package_update_latest.sh index 80323555..b91462d9 100755 --- a/Scripts/package_update_latest.sh +++ b/Scripts/package_update_latest.sh @@ -6,4 +6,4 @@ set -e export MVK_PKG_PATH="${PROJECT_DIR}/Package" # Assign symlink to Latest -ln -sfn "${MVK_PKG_PATH}/${CONFIGURATION}" "${MVK_PKG_PATH}/Latest" +ln -sfn "${CONFIGURATION}" "${MVK_PKG_PATH}/Latest"