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.
This commit is contained in:
Bill Hollings 2019-03-22 19:36:21 -04:00
parent fbc66c1ea3
commit 0ac1edbac0
19 changed files with 130 additions and 57 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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/

View File

@ -406,21 +406,25 @@ id<MTLFunction> MVKCommandResourceFactory::getFunctionNamed(const char* funcName
}
id<MTLFunction> MVKCommandResourceFactory::newMTLFunction(NSString* mslSrcCode, NSString* funcName) {
uint64_t startTime = _device->getPerformanceTimestamp();
NSError* err = nil;
id<MTLLibrary> 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<MTLLibrary> 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<MTLFunction> mtlFunc = [mtlLib newFunctionWithName: funcName];
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.functionRetrieval, startTime);
return mtlFunc;
startTime = _device->getPerformanceTimestamp();
id<MTLFunction> mtlFunc = [mtlLib newFunctionWithName: funcName];
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.functionRetrieval, startTime);
return mtlFunc;
}
}
id<MTLRenderPipelineState> 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.

View File

@ -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<MTLLibrary> 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();

View File

@ -194,7 +194,10 @@ void MVKMetalCompiler::compile(unique_lock<mutex>& 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.

View File

@ -126,8 +126,7 @@ id<MTLRenderPipelineState> MVKWatermark::newRenderPipelineState() {
NSError* err = nil;
id<MTLRenderPipelineState> 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<MTLLibrary> 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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 = "<group>"; };
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 = "<group>"; };
A95096BE2003D32400F10950 /* DirectorySupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectorySupport.h; sourceTree = "<group>"; };
A95096BD2003D32400F10950 /* OSSupport.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSSupport.mm; sourceTree = "<group>"; };
A95096BE2003D32400F10950 /* OSSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSSupport.h; sourceTree = "<group>"; };
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 = "<group>"; };
A97CC73F1C7527F3004A5C7E /* MoltenVKShaderConverterTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoltenVKShaderConverterTool.h; sourceTree = "<group>"; };
A98149651FB6A98A005F00B4 /* MVKStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKStrings.h; sourceTree = "<group>"; };
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 = "<group>"; };
@ -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;

View File

@ -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<uint32_t>& 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<char> 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;
}
}

View File

@ -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);
}

View File

@ -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 <Foundation/Foundation.h>
#import <Metal/Metal.h>
using namespace std;
using namespace mvk;
@ -60,3 +61,14 @@ template bool mvk::iterateDirectory<MoltenVKShaderConverterTool>(const string& d
bool isRecursive,
string& errMsg);
bool mvk::compile(const string& mslSourceCode, string& errMsg) {
@autoreleasepool {
NSError* err = nil;
id<MTLLibrary> 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;
}
}

View File

@ -181,11 +181,16 @@ 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 `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*.

View File

@ -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

View File

@ -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}"

View File

@ -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"

View File

@ -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"

View File

@ -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"