Add support for the VK_NV_glsl_shader extension.

Support runtime shader compilation from GLSL.
Return VK_ERROR_INVALID_SHADER_NV on shader and pipeline compilation errors.
Add MVKShaderCompilationPerformance::glslToSPRIV to track GLSL conversion performance.
Rename MoltenVKGLSLToSPIRVConverter MVKShaderStage enum to MVKGLSLConversionShaderStage
to avoid naming conflicts with MoltenVK MVKShaderStage enum.
Hologram demo load SPIR-V directly instead of using GLSL through either
MoltenVKGLSLToSPIRVConverter or VK_NV_glsl_shader extension.
Update to latest version of VulkanSamples that supports MVKGLSLConversionShaderStage.
This commit is contained in:
Bill Hollings 2019-05-10 12:21:03 -04:00
parent f79ccdfd94
commit c3aaf976ae
19 changed files with 197 additions and 160 deletions

View File

@ -9,12 +9,6 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
A99789AF1CD3D4E2005E7DAC /* Hologram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789831CD3D4E2005E7DAC /* Hologram.cpp */; }; A99789AF1CD3D4E2005E7DAC /* Hologram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789831CD3D4E2005E7DAC /* Hologram.cpp */; };
A99789B01CD3D4E2005E7DAC /* Hologram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789831CD3D4E2005E7DAC /* Hologram.cpp */; }; A99789B01CD3D4E2005E7DAC /* Hologram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789831CD3D4E2005E7DAC /* Hologram.cpp */; };
A99789B11CD3D4E2005E7DAC /* Hologram.frag in Resources */ = {isa = PBXBuildFile; fileRef = A99789841CD3D4E2005E7DAC /* Hologram.frag */; };
A99789B21CD3D4E2005E7DAC /* Hologram.frag in Resources */ = {isa = PBXBuildFile; fileRef = A99789841CD3D4E2005E7DAC /* Hologram.frag */; };
A99789B31CD3D4E2005E7DAC /* Hologram.push_constant.vert in Resources */ = {isa = PBXBuildFile; fileRef = A99789861CD3D4E2005E7DAC /* Hologram.push_constant.vert */; };
A99789B41CD3D4E2005E7DAC /* Hologram.push_constant.vert in Resources */ = {isa = PBXBuildFile; fileRef = A99789861CD3D4E2005E7DAC /* Hologram.push_constant.vert */; };
A99789B51CD3D4E2005E7DAC /* Hologram.vert in Resources */ = {isa = PBXBuildFile; fileRef = A99789871CD3D4E2005E7DAC /* Hologram.vert */; };
A99789B61CD3D4E2005E7DAC /* Hologram.vert in Resources */ = {isa = PBXBuildFile; fileRef = A99789871CD3D4E2005E7DAC /* Hologram.vert */; };
A99789B71CD3D4E2005E7DAC /* Main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789881CD3D4E2005E7DAC /* Main.cpp */; }; A99789B71CD3D4E2005E7DAC /* Main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789881CD3D4E2005E7DAC /* Main.cpp */; };
A99789B81CD3D4E2005E7DAC /* Main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789881CD3D4E2005E7DAC /* Main.cpp */; }; A99789B81CD3D4E2005E7DAC /* Main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789881CD3D4E2005E7DAC /* Main.cpp */; };
A99789B91CD3D4E2005E7DAC /* Meshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789891CD3D4E2005E7DAC /* Meshes.cpp */; }; A99789B91CD3D4E2005E7DAC /* Meshes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A99789891CD3D4E2005E7DAC /* Meshes.cpp */; };
@ -38,8 +32,6 @@
A9B67B901C3AAEA200373FFD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9B67B8A1C3AAEA200373FFD /* Main.storyboard */; }; A9B67B901C3AAEA200373FFD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9B67B8A1C3AAEA200373FFD /* Main.storyboard */; };
A9B67B911C3AAEA200373FFD /* macOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A9B67B8B1C3AAEA200373FFD /* macOS.xcassets */; }; A9B67B911C3AAEA200373FFD /* macOS.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A9B67B8B1C3AAEA200373FFD /* macOS.xcassets */; };
A9C2AB99218503A400DDBC03 /* libMoltenVK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9C2AB97218503A400DDBC03 /* libMoltenVK.a */; }; A9C2AB99218503A400DDBC03 /* libMoltenVK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9C2AB97218503A400DDBC03 /* libMoltenVK.a */; };
A9C2AB9A218503A400DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9C2AB98218503A400DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework */; };
A9C2AB9D218503BA00DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9C2AB9B218503BA00DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework */; };
A9C2AB9E218503BA00DDBC03 /* libMoltenVK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9C2AB9C218503BA00DDBC03 /* libMoltenVK.a */; }; A9C2AB9E218503BA00DDBC03 /* libMoltenVK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A9C2AB9C218503BA00DDBC03 /* libMoltenVK.a */; };
A9D516F81CD575E300097D96 /* HelpersDispatchTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9D516F61CD575E300097D96 /* HelpersDispatchTable.cpp */; }; A9D516F81CD575E300097D96 /* HelpersDispatchTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9D516F61CD575E300097D96 /* HelpersDispatchTable.cpp */; };
A9D516F91CD575E300097D96 /* HelpersDispatchTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9D516F61CD575E300097D96 /* HelpersDispatchTable.cpp */; }; A9D516F91CD575E300097D96 /* HelpersDispatchTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9D516F61CD575E300097D96 /* HelpersDispatchTable.cpp */; };
@ -47,16 +39,16 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1D6058910D05DD3D006BFB54 /* Hologram.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Hologram.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1D6058910D05DD3D006BFB54 /* Hologram.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Hologram.app; sourceTree = BUILT_PRODUCTS_DIR; };
A93374642284CD260059D36E /* Hologram.vert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Hologram.vert.h; path = android/src/main/jni/Hologram.vert.h; sourceTree = "<group>"; };
A93374652284CD260059D36E /* Hologram.push_constant.vert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Hologram.push_constant.vert.h; path = android/src/main/jni/Hologram.push_constant.vert.h; sourceTree = "<group>"; };
A93374662284CD260059D36E /* Hologram.frag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Hologram.frag.h; path = android/src/main/jni/Hologram.frag.h; sourceTree = "<group>"; };
A93CC3701CD56B8F00EB8A56 /* generate-dispatch-table */ = {isa = PBXFileReference; explicitFileType = text.script.python; path = "generate-dispatch-table"; sourceTree = "<group>"; }; A93CC3701CD56B8F00EB8A56 /* generate-dispatch-table */ = {isa = PBXFileReference; explicitFileType = text.script.python; path = "generate-dispatch-table"; sourceTree = "<group>"; };
A93CC3711CD56FD600EB8A56 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; }; A93CC3711CD56FD600EB8A56 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
A977BCFE1B66BB010067E5BF /* Hologram.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Hologram.app; sourceTree = BUILT_PRODUCTS_DIR; }; A977BCFE1B66BB010067E5BF /* Hologram.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Hologram.app; sourceTree = BUILT_PRODUCTS_DIR; };
A997897F1CD3D4E2005E7DAC /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Game.h; sourceTree = "<group>"; }; A997897F1CD3D4E2005E7DAC /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Game.h; sourceTree = "<group>"; };
A99789821CD3D4E2005E7DAC /* Helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Helpers.h; sourceTree = "<group>"; }; A99789821CD3D4E2005E7DAC /* Helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Helpers.h; sourceTree = "<group>"; };
A99789831CD3D4E2005E7DAC /* Hologram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hologram.cpp; sourceTree = "<group>"; }; A99789831CD3D4E2005E7DAC /* Hologram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hologram.cpp; sourceTree = "<group>"; };
A99789841CD3D4E2005E7DAC /* Hologram.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = Hologram.frag; sourceTree = "<group>"; };
A99789851CD3D4E2005E7DAC /* Hologram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hologram.h; sourceTree = "<group>"; }; A99789851CD3D4E2005E7DAC /* Hologram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hologram.h; sourceTree = "<group>"; };
A99789861CD3D4E2005E7DAC /* Hologram.push_constant.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = Hologram.push_constant.vert; sourceTree = "<group>"; };
A99789871CD3D4E2005E7DAC /* Hologram.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = Hologram.vert; sourceTree = "<group>"; };
A99789881CD3D4E2005E7DAC /* Main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Main.cpp; sourceTree = "<group>"; }; A99789881CD3D4E2005E7DAC /* Main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Main.cpp; sourceTree = "<group>"; };
A99789891CD3D4E2005E7DAC /* Meshes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Meshes.cpp; sourceTree = "<group>"; }; A99789891CD3D4E2005E7DAC /* Meshes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Meshes.cpp; sourceTree = "<group>"; };
A997898A1CD3D4E2005E7DAC /* Meshes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Meshes.h; sourceTree = "<group>"; }; A997898A1CD3D4E2005E7DAC /* Meshes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Meshes.h; sourceTree = "<group>"; };
@ -88,8 +80,6 @@
A9B67B8A1C3AAEA200373FFD /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; }; A9B67B8A1C3AAEA200373FFD /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
A9B67B8B1C3AAEA200373FFD /* macOS.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = macOS.xcassets; sourceTree = "<group>"; }; A9B67B8B1C3AAEA200373FFD /* macOS.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = macOS.xcassets; sourceTree = "<group>"; };
A9C2AB97218503A400DDBC03 /* libMoltenVK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMoltenVK.a; path = ../../../MoltenVK/iOS/static/libMoltenVK.a; sourceTree = "<group>"; }; A9C2AB97218503A400DDBC03 /* libMoltenVK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMoltenVK.a; path = ../../../MoltenVK/iOS/static/libMoltenVK.a; sourceTree = "<group>"; };
A9C2AB98218503A400DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MoltenVKGLSLToSPIRVConverter.framework; path = ../../../MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/iOS/framework/MoltenVKGLSLToSPIRVConverter.framework; sourceTree = "<group>"; };
A9C2AB9B218503BA00DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MoltenVKGLSLToSPIRVConverter.framework; path = ../../../MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/macOS/framework/MoltenVKGLSLToSPIRVConverter.framework; sourceTree = "<group>"; };
A9C2AB9C218503BA00DDBC03 /* libMoltenVK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMoltenVK.a; path = ../../../MoltenVK/macOS/static/libMoltenVK.a; sourceTree = "<group>"; }; A9C2AB9C218503BA00DDBC03 /* libMoltenVK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMoltenVK.a; path = ../../../MoltenVK/macOS/static/libMoltenVK.a; sourceTree = "<group>"; };
A9D516F61CD575E300097D96 /* HelpersDispatchTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HelpersDispatchTable.cpp; sourceTree = "<group>"; }; A9D516F61CD575E300097D96 /* HelpersDispatchTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HelpersDispatchTable.cpp; sourceTree = "<group>"; };
A9D516F71CD575E300097D96 /* HelpersDispatchTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpersDispatchTable.h; sourceTree = "<group>"; }; A9D516F71CD575E300097D96 /* HelpersDispatchTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpersDispatchTable.h; sourceTree = "<group>"; };
@ -101,7 +91,6 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A9C2AB99218503A400DDBC03 /* libMoltenVK.a in Frameworks */, A9C2AB99218503A400DDBC03 /* libMoltenVK.a in Frameworks */,
A9C2AB9A218503A400DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -110,7 +99,6 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A9C2AB9E218503BA00DDBC03 /* libMoltenVK.a in Frameworks */, A9C2AB9E218503BA00DDBC03 /* libMoltenVK.a in Frameworks */,
A9C2AB9D218503BA00DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -147,10 +135,10 @@
A997897F1CD3D4E2005E7DAC /* Game.h */, A997897F1CD3D4E2005E7DAC /* Game.h */,
A99789821CD3D4E2005E7DAC /* Helpers.h */, A99789821CD3D4E2005E7DAC /* Helpers.h */,
A99789831CD3D4E2005E7DAC /* Hologram.cpp */, A99789831CD3D4E2005E7DAC /* Hologram.cpp */,
A99789841CD3D4E2005E7DAC /* Hologram.frag */,
A99789851CD3D4E2005E7DAC /* Hologram.h */, A99789851CD3D4E2005E7DAC /* Hologram.h */,
A99789861CD3D4E2005E7DAC /* Hologram.push_constant.vert */, A93374662284CD260059D36E /* Hologram.frag.h */,
A99789871CD3D4E2005E7DAC /* Hologram.vert */, A93374652284CD260059D36E /* Hologram.push_constant.vert.h */,
A93374642284CD260059D36E /* Hologram.vert.h */,
A99789881CD3D4E2005E7DAC /* Main.cpp */, A99789881CD3D4E2005E7DAC /* Main.cpp */,
A99789891CD3D4E2005E7DAC /* Meshes.cpp */, A99789891CD3D4E2005E7DAC /* Meshes.cpp */,
A997898A1CD3D4E2005E7DAC /* Meshes.h */, A997898A1CD3D4E2005E7DAC /* Meshes.h */,
@ -220,9 +208,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A9C2AB9C218503BA00DDBC03 /* libMoltenVK.a */, A9C2AB9C218503BA00DDBC03 /* libMoltenVK.a */,
A9C2AB9B218503BA00DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework */,
A9C2AB97218503A400DDBC03 /* libMoltenVK.a */, A9C2AB97218503A400DDBC03 /* libMoltenVK.a */,
A9C2AB98218503A400DDBC03 /* MoltenVKGLSLToSPIRVConverter.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -312,12 +298,9 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A99789B51CD3D4E2005E7DAC /* Hologram.vert in Resources */,
A9B67B7F1C3AAE9800373FFD /* Icon.png in Resources */, A9B67B7F1C3AAE9800373FFD /* Icon.png in Resources */,
A99789B31CD3D4E2005E7DAC /* Hologram.push_constant.vert in Resources */,
A9B67B801C3AAE9800373FFD /* Main.storyboard in Resources */, A9B67B801C3AAE9800373FFD /* Main.storyboard in Resources */,
A9B67B7E1C3AAE9800373FFD /* Default~ipad.png in Resources */, A9B67B7E1C3AAE9800373FFD /* Default~ipad.png in Resources */,
A99789B11CD3D4E2005E7DAC /* Hologram.frag in Resources */,
A9B67B7D1C3AAE9800373FFD /* Default-568h@2x.png in Resources */, A9B67B7D1C3AAE9800373FFD /* Default-568h@2x.png in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -327,10 +310,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A9B67B911C3AAEA200373FFD /* macOS.xcassets in Resources */, A9B67B911C3AAEA200373FFD /* macOS.xcassets in Resources */,
A99789B21CD3D4E2005E7DAC /* Hologram.frag in Resources */,
A9B67B901C3AAEA200373FFD /* Main.storyboard in Resources */, A9B67B901C3AAEA200373FFD /* Main.storyboard in Resources */,
A99789B41CD3D4E2005E7DAC /* Hologram.push_constant.vert in Resources */,
A99789B61CD3D4E2005E7DAC /* Hologram.vert in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -379,9 +359,7 @@
buildSettings = { buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/iOS/framework\"";
GCC_PREFIX_HEADER = "$(SRCROOT)/iOS/Prefix.pch"; GCC_PREFIX_HEADER = "$(SRCROOT)/iOS/Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/iOS/static\""; LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/iOS/static\"";
@ -396,9 +374,7 @@
buildSettings = { buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/iOS/framework\"";
GCC_PREFIX_HEADER = "$(SRCROOT)/iOS/Prefix.pch"; GCC_PREFIX_HEADER = "$(SRCROOT)/iOS/Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/iOS/static\""; LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/iOS/static\"";
@ -413,9 +389,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/macOS/framework\"";
GCC_PREFIX_HEADER = "$(SRCROOT)/macOS/Prefix.pch"; GCC_PREFIX_HEADER = "$(SRCROOT)/macOS/Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/macOS/Info.plist";
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/macOS/static\""; LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/macOS/static\"";
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.11;
@ -432,9 +406,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVKShaderConverter/MoltenVKGLSLToSPIRVConverter/macOS/framework\"";
GCC_PREFIX_HEADER = "$(SRCROOT)/macOS/Prefix.pch"; GCC_PREFIX_HEADER = "$(SRCROOT)/macOS/Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info.plist"; INFOPLIST_FILE = "$(SRCROOT)/macOS/Info.plist";
LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/macOS/static\""; LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../MoltenVK/macOS/static\"";
MACOSX_DEPLOYMENT_TARGET = 10.11; MACOSX_DEPLOYMENT_TARGET = 10.11;
@ -463,7 +435,6 @@
"DEBUG=1", "DEBUG=1",
_DEBUG, _DEBUG,
GLM_FORCE_RADIANS, GLM_FORCE_RADIANS,
MVK_USE_MOLTENVK_SHADER_CONVERTER,
); );
GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
@ -471,7 +442,6 @@
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../../../MoltenVK/include\"", "\"$(SRCROOT)/../../../MoltenVK/include\"",
"\"$(SRCROOT)/../VulkanSamples/API-Samples/utils\"", "\"$(SRCROOT)/../VulkanSamples/API-Samples/utils\"",
"\"$(SRCROOT)/../../../MoltenVKShaderConverter/include\"",
); );
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
@ -490,17 +460,13 @@
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GCC_C_LANGUAGE_STANDARD = c99; GCC_C_LANGUAGE_STANDARD = c99;
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = GLM_FORCE_RADIANS;
GLM_FORCE_RADIANS,
MVK_USE_MOLTENVK_SHADER_CONVERTER,
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../../../MoltenVK/include\"", "\"$(SRCROOT)/../../../MoltenVK/include\"",
"\"$(SRCROOT)/../VulkanSamples/API-Samples/utils\"", "\"$(SRCROOT)/../VulkanSamples/API-Samples/utils\"",
"\"$(SRCROOT)/../../../MoltenVKShaderConverter/include\"",
); );
OTHER_LDFLAGS = "-ObjC"; OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.moltenvk.${PRODUCT_NAME:identifier}"; PRODUCT_BUNDLE_IDENTIFIER = "com.moltenvk.${PRODUCT_NAME:identifier}";

View File

@ -109,12 +109,6 @@ The demo allows some customization, by modifying the arguments passed to the dem
To customize, modify the arguments created in the `DemoViewController viewDidLoad` method To customize, modify the arguments created in the `DemoViewController viewDidLoad` method
found in the `iOS/DemoViewController.mm` or `macOS/DemoViewController.mm` file. found in the `iOS/DemoViewController.mm` or `macOS/DemoViewController.mm` file.
This demo illustrates the use of the **MoltenVK** API `vkGetMoltenVKDeviceConfigurationMVK()`
and `vkSetMoltenVKDeviceConfigurationMVK()` functions to enable **MoltenVK** debugging, including
logging the conversion of shaders from *SPIR-V* to *Metal Shading Language*. See the use of these
functions in the `Hologram/Hologram.cpp` file. To see the effect, modify the `Hologram-iOS` or
`Hologram-macOS` *Scheme* from within *Xcode* to use the **Debug** *Build Configuration* setting.
The `Hologram` demo is a simple example of installing **MoltenVK** as a *static library*. The `Hologram` demo is a simple example of installing **MoltenVK** as a *static library*.

View File

@ -260,6 +260,7 @@ In addition to the core *Vulkan* API, **MoltenVK** also supports the following
- `VK_AMD_gpu_shader_half_float` - `VK_AMD_gpu_shader_half_float`
- `VK_AMD_negative_viewport_height` - `VK_AMD_negative_viewport_height`
- `VK_IMG_format_pvrtc` (iOS) - `VK_IMG_format_pvrtc` (iOS)
- `VK_NV_glsl_shader`
In order to visibly display your content on *iOS* or *macOS*, you must enable the `VK_MVK_ios_surface` In order to visibly display your content on *iOS* or *macOS*, you must enable the `VK_MVK_ios_surface`
or `VK_MVK_macos_surface` extension, respectively, and use the functions defined for that extension or `VK_MVK_macos_surface` extension, respectively, and use the functions defined for that extension

View File

@ -19,6 +19,7 @@ MoltenVK 1.0.35
Released TBD Released TBD
- Support the `VK_EXT_debug_report` extension. - Support the `VK_EXT_debug_report` extension.
- Support the `VK_NV_glsl_shader` extension.
- Change log indication of error in logs from `[***MoltenVK ERROR***]` to - Change log indication of error in logs from `[***MoltenVK ERROR***]` to
`[mvk-error]`, for consistency with other log level indications. `[mvk-error]`, for consistency with other log level indications.
- Tessellation fixes: - Tessellation fixes:

View File

@ -1 +1 @@
07b1ccd82ff6b7e6369a0d8d6a5e5e4f7ba0b7d6 37e808988e758ec4f6f689012fb425bab1398ecf

View File

@ -222,6 +222,20 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
A96B8156227BF6FD008A772B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A9C86CB61C55B8350096CAF2 /* MoltenVKShaderConverter.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A937472B1A9A8B2900F29B34;
remoteInfo = "MoltenVKGLSLToSPIRVConverter-iOS";
};
A96B8158227BF715008A772B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A9C86CB61C55B8350096CAF2 /* MoltenVKShaderConverter.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = A93747701A9A98D000F29B34;
remoteInfo = "MoltenVKGLSLToSPIRVConverter-macOS";
};
A981497B1FB6B566005F00B4 /* PBXContainerItemProxy */ = { A981497B1FB6B566005F00B4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = A9C86CB61C55B8350096CAF2 /* MoltenVKShaderConverter.xcodeproj */; containerPortal = A9C86CB61C55B8350096CAF2 /* MoltenVKShaderConverter.xcodeproj */;
@ -763,6 +777,7 @@
); );
dependencies = ( dependencies = (
A981499B1FB6B9CF005F00B4 /* PBXTargetDependency */, A981499B1FB6B9CF005F00B4 /* PBXTargetDependency */,
A96B8157227BF6FD008A772B /* PBXTargetDependency */,
); );
name = "MoltenVK-iOS"; name = "MoltenVK-iOS";
productName = MoltenVK; productName = MoltenVK;
@ -782,6 +797,7 @@
); );
dependencies = ( dependencies = (
A98149A41FB6B9EB005F00B4 /* PBXTargetDependency */, A98149A41FB6B9EB005F00B4 /* PBXTargetDependency */,
A96B8159227BF715008A772B /* PBXTargetDependency */,
); );
name = "MoltenVK-macOS"; name = "MoltenVK-macOS";
productName = MoltenVK; productName = MoltenVK;
@ -1048,6 +1064,16 @@
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */ /* Begin PBXTargetDependency section */
A96B8157227BF6FD008A772B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVKGLSLToSPIRVConverter-iOS";
targetProxy = A96B8156227BF6FD008A772B /* PBXContainerItemProxy */;
};
A96B8159227BF715008A772B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "MoltenVKGLSLToSPIRVConverter-macOS";
targetProxy = A96B8158227BF715008A772B /* PBXContainerItemProxy */;
};
A981499B1FB6B9CF005F00B4 /* PBXTargetDependency */ = { A981499B1FB6B9CF005F00B4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
name = "MVKSPIRVToMSLConverter-iOS"; name = "MVKSPIRVToMSLConverter-iOS";
@ -1157,7 +1183,7 @@
MACH_O_TYPE = staticlib; MACH_O_TYPE = staticlib;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
PRELINK_LIBS = "${CONFIGURATION_BUILD_DIR}/libMoltenVKSPIRVToMSLConverter.a"; PRELINK_LIBS = "${CONFIGURATION_BUILD_DIR}/libMoltenVKSPIRVToMSLConverter.a ${CONFIGURATION_BUILD_DIR}/libMoltenVKGLSLToSPIRVConverter.a";
PRODUCT_NAME = MoltenVK; PRODUCT_NAME = MoltenVK;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
}; };
@ -1214,7 +1240,7 @@
); );
MACH_O_TYPE = staticlib; MACH_O_TYPE = staticlib;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRELINK_LIBS = "${CONFIGURATION_BUILD_DIR}/libMoltenVKSPIRVToMSLConverter.a"; PRELINK_LIBS = "${CONFIGURATION_BUILD_DIR}/libMoltenVKSPIRVToMSLConverter.a ${CONFIGURATION_BUILD_DIR}/libMoltenVKGLSLToSPIRVConverter.a";
PRODUCT_NAME = MoltenVK; PRODUCT_NAME = MoltenVK;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;

View File

@ -566,6 +566,7 @@ typedef struct {
MVKPerformanceTracker functionRetrieval; /** Retrieve a MTLFunction from a MTLLibrary. */ MVKPerformanceTracker functionRetrieval; /** Retrieve a MTLFunction from a MTLLibrary. */
MVKPerformanceTracker functionSpecialization; /** Specialize a retrieved MTLFunction. */ MVKPerformanceTracker functionSpecialization; /** Specialize a retrieved MTLFunction. */
MVKPerformanceTracker pipelineCompile; /** Compile MTLFunctions into a pipeline. */ MVKPerformanceTracker pipelineCompile; /** Compile MTLFunctions into a pipeline. */
MVKPerformanceTracker glslToSPRIV; /** Convert GLSL to SPIR-V code. */
} MVKShaderCompilationPerformance; } MVKShaderCompilationPerformance;

View File

@ -703,7 +703,7 @@ bool MVKGraphicsPipeline::addVertexShaderToPipeline(MTLRenderPipelineDescriptor*
addVertexInputToShaderConverterContext(shaderContext, pCreateInfo); addVertexInputToShaderConverterContext(shaderContext, pCreateInfo);
id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pVertexSS->module)->getMTLFunction(&shaderContext, _pVertexSS->pSpecializationInfo, _pipelineCache).mtlFunction; id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pVertexSS->module)->getMTLFunction(&shaderContext, _pVertexSS->pSpecializationInfo, _pipelineCache).mtlFunction;
if ( !mtlFunction ) { if ( !mtlFunction ) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Vertex shader function could not be compiled into pipeline. See previous logged error.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Vertex shader function could not be compiled into pipeline. See previous logged error."));
return false; return false;
} }
plDesc.vertexFunction = mtlFunction; plDesc.vertexFunction = mtlFunction;
@ -712,16 +712,16 @@ bool MVKGraphicsPipeline::addVertexShaderToPipeline(MTLRenderPipelineDescriptor*
_needsVertexOutputBuffer = shaderContext.options.needsOutputBuffer; _needsVertexOutputBuffer = shaderContext.options.needsOutputBuffer;
// If we need the auxiliary buffer and there's no place to put it, we're in serious trouble. // If we need the auxiliary buffer and there's no place to put it, we're in serious trouble.
if (_needsVertexAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageVertex] >= _device->_pMetalFeatures->maxPerStageBufferCount - vbCnt) { if (_needsVertexAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageVertex] >= _device->_pMetalFeatures->maxPerStageBufferCount - vbCnt) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Vertex shader requires auxiliary buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Vertex shader requires auxiliary buffer, but there is no free slot to pass it."));
return false; return false;
} }
// Ditto captured output buffer. // Ditto captured output buffer.
if (_needsVertexOutputBuffer && _outputBufferIndex.stages[kMVKShaderStageVertex] >= _device->_pMetalFeatures->maxPerStageBufferCount - vbCnt) { if (_needsVertexOutputBuffer && _outputBufferIndex.stages[kMVKShaderStageVertex] >= _device->_pMetalFeatures->maxPerStageBufferCount - vbCnt) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Vertex shader requires output buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Vertex shader requires output buffer, but there is no free slot to pass it."));
return false; return false;
} }
if (_needsVertexOutputBuffer && _indirectParamsIndex.stages[kMVKShaderStageVertex] >= _device->_pMetalFeatures->maxPerStageBufferCount - vbCnt) { if (_needsVertexOutputBuffer && _indirectParamsIndex.stages[kMVKShaderStageVertex] >= _device->_pMetalFeatures->maxPerStageBufferCount - vbCnt) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Vertex shader requires indirect parameters buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Vertex shader requires indirect parameters buffer, but there is no free slot to pass it."));
return false; return false;
} }
return true; return true;
@ -739,7 +739,7 @@ bool MVKGraphicsPipeline::addTessCtlShaderToPipeline(MTLComputePipelineDescripto
addPrevStageOutputToShaderConverterContext(shaderContext, vtxOutputs); addPrevStageOutputToShaderConverterContext(shaderContext, vtxOutputs);
id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pTessCtlSS->module)->getMTLFunction(&shaderContext, _pTessCtlSS->pSpecializationInfo, _pipelineCache).mtlFunction; id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pTessCtlSS->module)->getMTLFunction(&shaderContext, _pTessCtlSS->pSpecializationInfo, _pipelineCache).mtlFunction;
if ( !mtlFunction ) { if ( !mtlFunction ) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation control shader function could not be compiled into pipeline. See previous logged error.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation control shader function could not be compiled into pipeline. See previous logged error."));
return false; return false;
} }
plDesc.computeFunction = mtlFunction; plDesc.computeFunction = mtlFunction;
@ -748,23 +748,23 @@ bool MVKGraphicsPipeline::addTessCtlShaderToPipeline(MTLComputePipelineDescripto
_needsTessCtlPatchOutputBuffer = shaderContext.options.needsPatchOutputBuffer; _needsTessCtlPatchOutputBuffer = shaderContext.options.needsPatchOutputBuffer;
_needsTessCtlInput = shaderContext.options.needsInputThreadgroupMem; _needsTessCtlInput = shaderContext.options.needsInputThreadgroupMem;
if (_needsTessCtlAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageTessCtl] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) { if (_needsTessCtlAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageTessCtl] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation control shader requires auxiliary buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation control shader requires auxiliary buffer, but there is no free slot to pass it."));
return false; return false;
} }
if (_indirectParamsIndex.stages[kMVKShaderStageTessCtl] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) { if (_indirectParamsIndex.stages[kMVKShaderStageTessCtl] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation control shader requires indirect parameters buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation control shader requires indirect parameters buffer, but there is no free slot to pass it."));
return false; return false;
} }
if (_needsTessCtlOutputBuffer && _outputBufferIndex.stages[kMVKShaderStageTessCtl] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) { if (_needsTessCtlOutputBuffer && _outputBufferIndex.stages[kMVKShaderStageTessCtl] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation control shader requires per-vertex output buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation control shader requires per-vertex output buffer, but there is no free slot to pass it."));
return false; return false;
} }
if (_needsTessCtlPatchOutputBuffer && _tessCtlPatchOutputBufferIndex >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) { if (_needsTessCtlPatchOutputBuffer && _tessCtlPatchOutputBufferIndex >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation control shader requires per-patch output buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation control shader requires per-patch output buffer, but there is no free slot to pass it."));
return false; return false;
} }
if (_tessCtlLevelBufferIndex >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) { if (_tessCtlLevelBufferIndex >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessCtlNumReservedBuffers) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation control shader requires tessellation level output buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation control shader requires tessellation level output buffer, but there is no free slot to pass it."));
return false; return false;
} }
return true; return true;
@ -779,7 +779,7 @@ bool MVKGraphicsPipeline::addTessEvalShaderToPipeline(MTLRenderPipelineDescripto
addPrevStageOutputToShaderConverterContext(shaderContext, tcOutputs); addPrevStageOutputToShaderConverterContext(shaderContext, tcOutputs);
id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pTessEvalSS->module)->getMTLFunction(&shaderContext, _pTessEvalSS->pSpecializationInfo, _pipelineCache).mtlFunction; id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pTessEvalSS->module)->getMTLFunction(&shaderContext, _pTessEvalSS->pSpecializationInfo, _pipelineCache).mtlFunction;
if ( !mtlFunction ) { if ( !mtlFunction ) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation evaluation shader function could not be compiled into pipeline. See previous logged error.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation evaluation shader function could not be compiled into pipeline. See previous logged error."));
return false; return false;
} }
// Yeah, you read that right. Tess. eval functions are a kind of vertex function in Metal. // Yeah, you read that right. Tess. eval functions are a kind of vertex function in Metal.
@ -788,7 +788,7 @@ bool MVKGraphicsPipeline::addTessEvalShaderToPipeline(MTLRenderPipelineDescripto
_needsTessEvalAuxBuffer = shaderContext.options.needsAuxBuffer; _needsTessEvalAuxBuffer = shaderContext.options.needsAuxBuffer;
// If we need the auxiliary buffer and there's no place to put it, we're in serious trouble. // If we need the auxiliary buffer and there's no place to put it, we're in serious trouble.
if (_needsTessEvalAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageTessEval] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessEvalNumReservedBuffers) { if (_needsTessEvalAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageTessEval] >= _device->_pMetalFeatures->maxPerStageBufferCount - kMVKTessEvalNumReservedBuffers) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Tessellation evaluation shader requires auxiliary buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Tessellation evaluation shader requires auxiliary buffer, but there is no free slot to pass it."));
return false; return false;
} }
return true; return true;
@ -802,13 +802,13 @@ bool MVKGraphicsPipeline::addFragmentShaderToPipeline(MTLRenderPipelineDescripto
shaderContext.options.shouldCaptureOutput = false; shaderContext.options.shouldCaptureOutput = false;
id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pFragmentSS->module)->getMTLFunction(&shaderContext, _pFragmentSS->pSpecializationInfo, _pipelineCache).mtlFunction; id<MTLFunction> mtlFunction = ((MVKShaderModule*)_pFragmentSS->module)->getMTLFunction(&shaderContext, _pFragmentSS->pSpecializationInfo, _pipelineCache).mtlFunction;
if ( !mtlFunction ) { if ( !mtlFunction ) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Fragment shader function could not be compiled into pipeline. See previous logged error.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Fragment shader function could not be compiled into pipeline. See previous logged error."));
return false; return false;
} }
plDesc.fragmentFunction = mtlFunction; plDesc.fragmentFunction = mtlFunction;
_needsFragmentAuxBuffer = shaderContext.options.needsAuxBuffer; _needsFragmentAuxBuffer = shaderContext.options.needsAuxBuffer;
if (_needsFragmentAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageFragment] >= _device->_pMetalFeatures->maxPerStageBufferCount) { if (_needsFragmentAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageFragment] >= _device->_pMetalFeatures->maxPerStageBufferCount) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Fragment shader requires auxiliary buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Fragment shader requires auxiliary buffer, but there is no free slot to pass it."));
return false; return false;
} }
} }
@ -1170,11 +1170,11 @@ MVKComputePipeline::MVKComputePipeline(MVKDevice* device,
_mtlPipelineState = plc->newMTLComputePipelineState(shaderFunc.mtlFunction); // retained _mtlPipelineState = plc->newMTLComputePipelineState(shaderFunc.mtlFunction); // retained
plc->destroy(); plc->destroy();
} else { } else {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Compute shader function could not be compiled into pipeline. See previous logged error.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Compute shader function could not be compiled into pipeline. See previous logged error."));
} }
if (_needsAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageCompute] > _device->_pMetalFeatures->maxPerStageBufferCount) { if (_needsAuxBuffer && _auxBufferIndex.stages[kMVKShaderStageCompute] > _device->_pMetalFeatures->maxPerStageBufferCount) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Compute shader requires auxiliary buffer, but there is no free slot to pass it.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "Compute shader requires auxiliary buffer, but there is no free slot to pass it."));
} }
} }

View File

@ -21,6 +21,7 @@
#include "MVKDevice.h" #include "MVKDevice.h"
#include "MVKSync.h" #include "MVKSync.h"
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h> #include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
#include <MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.h>
#include <vector> #include <vector>
#include <mutex> #include <mutex>
@ -167,22 +168,22 @@ public:
bool convert(SPIRVToMSLConverterContext* pContext); bool convert(SPIRVToMSLConverterContext* pContext);
/** Returns the original SPIR-V code that was specified when this object was created. */ /** Returns the original SPIR-V code that was specified when this object was created. */
inline const std::vector<uint32_t>& getSPIRV() { return _converter.getSPIRV(); } const std::vector<uint32_t>& getSPIRV() { return _spvConverter.getSPIRV(); }
/** /**
* Returns the Metal Shading Language source code as converted by the most recent * Returns the Metal Shading Language source code as converted by the most recent
* call to convert() function, or set directly using the setMSL() function. * call to convert() function, or set directly using the setMSL() function.
*/ */
inline const std::string& getMSL() { return _converter.getMSL(); } const std::string& getMSL() { return _spvConverter.getMSL(); }
/** /**
* Returns information about the shader entry point as converted by the most recent * Returns information about the shader entry point as converted by the most recent
* call to convert() function, or set directly using the setMSL() function. * call to convert() function, or set directly using the setMSL() function.
*/ */
inline const SPIRVEntryPoint& getEntryPoint() { return _converter.getEntryPoint(); } const SPIRVEntryPoint& getEntryPoint() { return _spvConverter.getEntryPoint(); }
/** Returns a key as a means of identifying this shader module in a pipeline cache. */ /** Returns a key as a means of identifying this shader module in a pipeline cache. */
inline MVKShaderModuleKey getKey() { return _key; } MVKShaderModuleKey getKey() { return _key; }
MVKShaderModule(MVKDevice* device, const VkShaderModuleCreateInfo* pCreateInfo); MVKShaderModule(MVKDevice* device, const VkShaderModuleCreateInfo* pCreateInfo);
@ -191,8 +192,11 @@ public:
protected: protected:
friend MVKShaderCacheIterator; friend MVKShaderCacheIterator;
MVKGLSLConversionShaderStage getMVKGLSLConversionShaderStage(SPIRVToMSLConverterContext* pContext);
MVKShaderLibraryCache _shaderLibraryCache; MVKShaderLibraryCache _shaderLibraryCache;
SPIRVToMSLConverter _converter; SPIRVToMSLConverter _spvConverter;
GLSLToSPIRVConverter _glslConverter;
MVKShaderLibrary* _defaultLibrary; MVKShaderLibrary* _defaultLibrary;
MVKShaderModuleKey _key; MVKShaderModuleKey _key;
std::mutex _accessLock; std::mutex _accessLock;

View File

@ -92,7 +92,7 @@ MVKMTLFunction MVKShaderLibrary::getMTLFunction(const VkSpecializationInfo* pSpe
} }
} }
} else { } else {
reportError(VK_ERROR_INITIALIZATION_FAILED, "Shader module does not contain an entry point named '%s'.", mtlFuncName.UTF8String); reportError(VK_ERROR_INVALID_SHADER_NV, "Shader module does not contain an entry point named '%s'.", mtlFuncName.UTF8String);
} }
return { mtlFunc, MTLSizeMake(getWorkgroupDimensionSize(_entryPoint.workgroupSize.width, pSpecializationInfo), return { mtlFunc, MTLSizeMake(getWorkgroupDimensionSize(_entryPoint.workgroupSize.width, pSpecializationInfo),
@ -150,7 +150,7 @@ void MVKShaderLibrary::handleCompilationError(NSError* err, const char* opDesc)
if (_mtlLibrary) { if (_mtlLibrary) {
MVKLogInfo("%s succeeded with warnings (Error code %li):\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 { } else {
_owner->setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, _owner->setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV,
"%s failed (Error code %li):\n%s", "%s failed (Error code %li):\n%s",
opDesc, (long)err.code, opDesc, (long)err.code,
err.localizedDescription.UTF8String)); err.localizedDescription.UTF8String));
@ -244,19 +244,53 @@ MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConverterContext* pCont
bool MVKShaderModule::convert(SPIRVToMSLConverterContext* pContext) { bool MVKShaderModule::convert(SPIRVToMSLConverterContext* pContext) {
bool shouldLogCode = _device->_pMVKConfig->debugMode; bool shouldLogCode = _device->_pMVKConfig->debugMode;
bool shouldLogEstimatedGLSL = shouldLogCode;
// If the SPIR-V converter does not have any code, but the GLSL converter does,
// convert the GLSL code to SPIR-V and set it into the SPIR-V conveter.
if ( !_spvConverter.hasSPIRV() && _glslConverter.hasGLSL() ) {
uint64_t startTime = _device->getPerformanceTimestamp();
bool wasConverted = _glslConverter.convert(getMVKGLSLConversionShaderStage(pContext), shouldLogCode, false);
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.glslToSPRIV, startTime);
if (wasConverted) {
if (shouldLogCode) { MVKLogInfo("%s", _glslConverter.getResultLog().c_str()); }
_spvConverter.setSPIRV(_glslConverter.getSPIRV());
} else {
reportError(VK_ERROR_INVALID_SHADER_NV, "Unable to convert GLSL to SPIR-V:\n%s", _glslConverter.getResultLog().c_str());
}
shouldLogEstimatedGLSL = false;
}
uint64_t startTime = _device->getPerformanceTimestamp(); uint64_t startTime = _device->getPerformanceTimestamp();
bool wasConverted = _converter.convert(*pContext, shouldLogCode, shouldLogCode, shouldLogCode); bool wasConverted = _spvConverter.convert(*pContext, shouldLogCode, shouldLogCode, shouldLogEstimatedGLSL);
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.spirvToMSL, startTime); _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.spirvToMSL, startTime);
if (wasConverted) { if (wasConverted) {
if (shouldLogCode) { MVKLogInfo("%s", _converter.getResultLog().data()); } if (shouldLogCode) { MVKLogInfo("%s", _spvConverter.getResultLog().c_str()); }
} else { } else {
reportError(VK_ERROR_FORMAT_NOT_SUPPORTED, "Unable to convert SPIR-V to MSL:\n%s", _converter.getResultLog().data()); reportError(VK_ERROR_INVALID_SHADER_NV, "Unable to convert SPIR-V to MSL:\n%s", _spvConverter.getResultLog().c_str());
} }
return wasConverted; return wasConverted;
} }
// Returns the MVKGLSLConversionShaderStage corresponding to the shader stage in the SPIR-V converter context.
MVKGLSLConversionShaderStage MVKShaderModule::getMVKGLSLConversionShaderStage(SPIRVToMSLConverterContext* pContext) {
switch (pContext->options.entryPointStage) {
case spv::ExecutionModelVertex: return kMVKGLSLConversionShaderStageVertex;
case spv::ExecutionModelTessellationControl: return kMVKGLSLConversionShaderStageTessControl;
case spv::ExecutionModelTessellationEvaluation: return kMVKGLSLConversionShaderStageTessEval;
case spv::ExecutionModelGeometry: return kMVKGLSLConversionShaderStageGeometry;
case spv::ExecutionModelFragment: return kMVKGLSLConversionShaderStageFragment;
case spv::ExecutionModelGLCompute: return kMVKGLSLConversionShaderStageCompute;
case spv::ExecutionModelKernel: return kMVKGLSLConversionShaderStageCompute;
default:
MVKAssert(false, "Bad shader stage provided for GLSL to SPIR-V conversion.");
return kMVKGLSLConversionShaderStageAuto;
}
}
#pragma mark Construction #pragma mark Construction
@ -270,7 +304,7 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
// Ensure something is there. // Ensure something is there.
if ( (pCreateInfo->pCode == VK_NULL_HANDLE) || (codeSize < 4) ) { if ( (pCreateInfo->pCode == VK_NULL_HANDLE) || (codeSize < 4) ) {
setConfigurationResult(reportError(VK_INCOMPLETE, "Shader module contains no SPIR-V code.")); setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "vkCreateShaderModule(): Shader module contains no shader code."));
return; return;
} }
@ -279,36 +313,36 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
// Retrieve the magic number to determine what type of shader code has been loaded. // Retrieve the magic number to determine what type of shader code has been loaded.
uint32_t magicNum = *pCreateInfo->pCode; uint32_t magicNum = *pCreateInfo->pCode;
switch (magicNum) { switch (magicNum) {
case kMVKMagicNumberSPIRVCode: { // SPIR-V code case kMVKMagicNumberSPIRVCode: { // SPIR-V code
size_t spvCount = (pCreateInfo->codeSize + 3) >> 2; // Round up if byte length not exactly on uint32_t boundary size_t spvCount = (codeSize + 3) >> 2; // Round up if byte length not exactly on uint32_t boundary
uint64_t startTime = _device->getPerformanceTimestamp(); uint64_t startTime = _device->getPerformanceTimestamp();
codeHash = mvkHash(pCreateInfo->pCode, spvCount); codeHash = mvkHash(pCreateInfo->pCode, spvCount);
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.hashShaderCode, startTime); _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.hashShaderCode, startTime);
_converter.setSPIRV(pCreateInfo->pCode, spvCount); _spvConverter.setSPIRV(pCreateInfo->pCode, spvCount);
break; break;
} }
case kMVKMagicNumberMSLSourceCode: { // MSL source code case kMVKMagicNumberMSLSourceCode: { // MSL source code
size_t hdrSize = sizeof(MVKMSLSPIRVHeader); size_t hdrSize = sizeof(MVKMSLSPIRVHeader);
char* pMSLCode = (char*)(uintptr_t(pCreateInfo->pCode) + hdrSize); char* pMSLCode = (char*)(uintptr_t(pCreateInfo->pCode) + hdrSize);
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize; size_t mslCodeLen = codeSize - hdrSize;
uint64_t startTime = _device->getPerformanceTimestamp(); uint64_t startTime = _device->getPerformanceTimestamp();
codeHash = mvkHash(&magicNum); codeHash = mvkHash(&magicNum);
codeHash = mvkHash(pMSLCode, mslCodeLen, codeHash); codeHash = mvkHash(pMSLCode, mslCodeLen, codeHash);
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.hashShaderCode, startTime); _device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.hashShaderCode, startTime);
_converter.setMSL(pMSLCode, nullptr); _spvConverter.setMSL(pMSLCode, nullptr);
_defaultLibrary = new MVKShaderLibrary(this, _converter.getMSL().c_str(), _converter.getEntryPoint()); _defaultLibrary = new MVKShaderLibrary(this, _spvConverter.getMSL().c_str(), _spvConverter.getEntryPoint());
break; break;
} }
case kMVKMagicNumberMSLCompiledCode: { // MSL compiled binary code case kMVKMagicNumberMSLCompiledCode: { // MSL compiled binary code
size_t hdrSize = sizeof(MVKMSLSPIRVHeader); size_t hdrSize = sizeof(MVKMSLSPIRVHeader);
char* pMSLCode = (char*)(uintptr_t(pCreateInfo->pCode) + hdrSize); char* pMSLCode = (char*)(uintptr_t(pCreateInfo->pCode) + hdrSize);
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize; size_t mslCodeLen = codeSize - hdrSize;
uint64_t startTime = _device->getPerformanceTimestamp(); uint64_t startTime = _device->getPerformanceTimestamp();
codeHash = mvkHash(&magicNum); codeHash = mvkHash(&magicNum);
@ -319,8 +353,19 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
break; break;
} }
default: default: // Could be GLSL source code
setConfigurationResult(reportError(VK_ERROR_FORMAT_NOT_SUPPORTED, "SPIR-V contains invalid magic number %x.", magicNum)); if (_device->_enabledExtensions.vk_NV_glsl_shader.enabled) {
const char* pGLSL = (char*)pCreateInfo->pCode;
size_t glslLen = codeSize - 1;
uint64_t startTime = _device->getPerformanceTimestamp();
codeHash = mvkHash(pGLSL, codeSize);
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.hashShaderCode, startTime);
_glslConverter.setGLSL(pGLSL, glslLen);
} else {
setConfigurationResult(reportError(VK_ERROR_INVALID_SHADER_NV, "vkCreateShaderModule(): The SPIR-V contains an invalid magic number %x.", magicNum));
}
break; break;
} }

View File

@ -63,7 +63,8 @@ MVK_EXTENSION(MVK_macos_surface, MVK_MACOS_SURFACE)
MVK_EXTENSION(MVK_moltenvk, MVK_MOLTENVK) MVK_EXTENSION(MVK_moltenvk, MVK_MOLTENVK)
MVK_EXTENSION(AMD_gpu_shader_half_float, AMD_GPU_SHADER_HALF_FLOAT) MVK_EXTENSION(AMD_gpu_shader_half_float, AMD_GPU_SHADER_HALF_FLOAT)
MVK_EXTENSION(AMD_negative_viewport_height, AMD_NEGATIVE_VIEWPORT_HEIGHT) MVK_EXTENSION(AMD_negative_viewport_height, AMD_NEGATIVE_VIEWPORT_HEIGHT)
MVK_EXTENSION_LAST(IMG_format_pvrtc, IMG_FORMAT_PVRTC) MVK_EXTENSION(IMG_format_pvrtc, IMG_FORMAT_PVRTC)
MVK_EXTENSION_LAST(NV_glsl_shader, NV_GLSL_SHADER)
#undef MVK_EXTENSION #undef MVK_EXTENSION
#undef MVK_EXTENSION_LAST #undef MVK_EXTENSION_LAST

View File

@ -32,14 +32,14 @@ extern "C" {
/** Enumeration of the pipeline stages for which a shader can be compiled. */ /** Enumeration of the pipeline stages for which a shader can be compiled. */
typedef enum { typedef enum {
kMVKShaderStageAuto, kMVKGLSLConversionShaderStageAuto,
kMVKShaderStageVertex, kMVKGLSLConversionShaderStageVertex,
kMVKShaderStageTessControl, kMVKGLSLConversionShaderStageTessControl,
kMVKShaderStageTessEval, kMVKGLSLConversionShaderStageTessEval,
kMVKShaderStageGeometry, kMVKGLSLConversionShaderStageGeometry,
kMVKShaderStageFragment, kMVKGLSLConversionShaderStageFragment,
kMVKShaderStageCompute, kMVKGLSLConversionShaderStageCompute,
} MVKShaderStage; } MVKGLSLConversionShaderStage;
/** /**
@ -63,7 +63,7 @@ typedef enum {
* should be logged to the converter results log. This can be useful during shader debugging. * should be logged to the converter results log. This can be useful during shader debugging.
*/ */
bool mvkConvertGLSLToSPIRV(const char* glslSource, bool mvkConvertGLSLToSPIRV(const char* glslSource,
MVKShaderStage shaderStage, MVKGLSLConversionShaderStage shaderStage,
uint32_t** pSPIRVCode, uint32_t** pSPIRVCode,
size_t *pSPIRVLength, size_t *pSPIRVLength,
char** pResultLog, char** pResultLog,
@ -90,7 +90,7 @@ bool mvkConvertGLSLToSPIRV(const char* glslSource,
* should be logged to the converter results log. This can be useful during shader debugging. * should be logged to the converter results log. This can be useful during shader debugging.
*/ */
bool mvkConvertGLSLFileToSPIRV(const char* glslFilepath, bool mvkConvertGLSLFileToSPIRV(const char* glslFilepath,
MVKShaderStage shaderStage, MVKGLSLConversionShaderStage shaderStage,
uint32_t** pSPIRVCode, uint32_t** pSPIRVCode,
size_t *pSPIRVLength, size_t *pSPIRVLength,
char** pResultLog, char** pResultLog,

View File

@ -26,7 +26,7 @@ using namespace mvk;
MVK_PUBLIC_SYMBOL bool mvkConvertGLSLToSPIRV(const char* glslSource, MVK_PUBLIC_SYMBOL bool mvkConvertGLSLToSPIRV(const char* glslSource,
MVKShaderStage shaderStage, MVKGLSLConversionShaderStage shaderStage,
uint32_t** pSPIRVCode, uint32_t** pSPIRVCode,
size_t *pSPIRVLength, size_t *pSPIRVLength,
char** pResultLog, char** pResultLog,
@ -59,7 +59,7 @@ MVK_PUBLIC_SYMBOL bool mvkConvertGLSLToSPIRV(const char* glslSource,
} }
MVK_PUBLIC_SYMBOL bool mvkConvertGLSLFileToSPIRV(const char* glslFilepath, MVK_PUBLIC_SYMBOL bool mvkConvertGLSLFileToSPIRV(const char* glslFilepath,
MVKShaderStage shaderStage, MVKGLSLConversionShaderStage shaderStage,
uint32_t** pSPIRVCode, uint32_t** pSPIRVCode,
size_t *pSPIRVLength, size_t *pSPIRVLength,
char** pResultLog, char** pResultLog,

View File

@ -37,13 +37,9 @@ using namespace mvk;
void configureGLSLCompilerResources(TBuiltInResource* glslCompilerResources); void configureGLSLCompilerResources(TBuiltInResource* glslCompilerResources);
/** Returns the GLSL compiler language type corresponding to the specified MoltenVK shader stage. */ /** Returns the GLSL compiler language type corresponding to the specified MoltenVK shader stage. */
EShLanguage eshLanguageFromMVKShaderStage(const MVKShaderStage mvkShaderStage); EShLanguage eshLanguageFromMVKGLSLConversionShaderStage(const MVKGLSLConversionShaderStage mvkShaderStage);
MVK_PUBLIC_SYMBOL void GLSLToSPIRVConverter::setGLSL(const string& glslSrc) { _glsl = glslSrc; } MVK_PUBLIC_SYMBOL bool GLSLToSPIRVConverter::convert(MVKGLSLConversionShaderStage shaderStage,
MVK_PUBLIC_SYMBOL const string& GLSLToSPIRVConverter::getGLSL() { return _glsl; }
MVK_PUBLIC_SYMBOL bool GLSLToSPIRVConverter::convert(MVKShaderStage shaderStage,
bool shouldLogGLSL, bool shouldLogGLSL,
bool shouldLogSPIRV) { bool shouldLogSPIRV) {
_wasConverted = true; _wasConverted = true;
@ -54,7 +50,7 @@ MVK_PUBLIC_SYMBOL bool GLSLToSPIRVConverter::convert(MVKShaderStage shaderStage,
EShMessages messages = (EShMessages)(EShMsgDefault | EShMsgSpvRules | EShMsgVulkanRules); EShMessages messages = (EShMessages)(EShMsgDefault | EShMsgSpvRules | EShMsgVulkanRules);
EShLanguage stage = eshLanguageFromMVKShaderStage(shaderStage); EShLanguage stage = eshLanguageFromMVKGLSLConversionShaderStage(shaderStage);
TBuiltInResource glslCompilerResources; TBuiltInResource glslCompilerResources;
configureGLSLCompilerResources(&glslCompilerResources); configureGLSLCompilerResources(&glslCompilerResources);
const char *glslStrings[1]; const char *glslStrings[1];
@ -91,12 +87,6 @@ MVK_PUBLIC_SYMBOL bool GLSLToSPIRVConverter::convert(MVKShaderStage shaderStage,
return _wasConverted; return _wasConverted;
} }
MVK_PUBLIC_SYMBOL const vector<uint32_t>& GLSLToSPIRVConverter::getSPIRV() { return _spirv; }
MVK_PUBLIC_SYMBOL bool GLSLToSPIRVConverter::getWasConverted() { return _wasConverted; }
MVK_PUBLIC_SYMBOL const string& GLSLToSPIRVConverter::getResultLog() { return _resultLog; }
/** Appends the message text to the result log. */ /** Appends the message text to the result log. */
void GLSLToSPIRVConverter::logMsg(const char* logMsg) { void GLSLToSPIRVConverter::logMsg(const char* logMsg) {
string trimMsg = trim(logMsg); string trimMsg = trim(logMsg);
@ -240,15 +230,15 @@ void configureGLSLCompilerResources(TBuiltInResource* glslCompilerResources) {
glslCompilerResources->limits.generalConstantMatrixVectorIndexing = 1; glslCompilerResources->limits.generalConstantMatrixVectorIndexing = 1;
} }
EShLanguage eshLanguageFromMVKShaderStage(const MVKShaderStage mvkShaderStage) { EShLanguage eshLanguageFromMVKGLSLConversionShaderStage(const MVKGLSLConversionShaderStage mvkShaderStage) {
switch (mvkShaderStage) { switch (mvkShaderStage) {
case kMVKShaderStageVertex: return EShLangVertex; case kMVKGLSLConversionShaderStageVertex: return EShLangVertex;
case kMVKShaderStageTessControl: return EShLangTessControl; case kMVKGLSLConversionShaderStageTessControl: return EShLangTessControl;
case kMVKShaderStageTessEval: return EShLangTessEvaluation; case kMVKGLSLConversionShaderStageTessEval: return EShLangTessEvaluation;
case kMVKShaderStageGeometry: return EShLangGeometry; case kMVKGLSLConversionShaderStageGeometry: return EShLangGeometry;
case kMVKShaderStageFragment: return EShLangFragment; case kMVKGLSLConversionShaderStageFragment: return EShLangFragment;
case kMVKShaderStageCompute: return EShLangCompute; case kMVKGLSLConversionShaderStageCompute: return EShLangCompute;
default: return EShLangVertex; default: return EShLangVertex;
} }
} }

View File

@ -35,11 +35,20 @@ namespace mvk {
public: public:
/** Sets the GLSL source code that is to be converted to the specified null-terminated string. */ /** Sets the GLSL source code that is to be converted to the specified string. */
void setGLSL(const std::string& glslSrc); void setGLSL(const std::string& glslSrc) { _glsl = glslSrc; }
/**
* Sets the GLSL source code that is to be converted from the first length characters
* of the buffer, and ensuring the resulting string is null-terminated.
*/
void setGLSL(const char* glslSrc, size_t length) { _glsl.assign(glslSrc, length); }
/** Returns the GLSL source code that was set using the setGLSL() function. */ /** Returns the GLSL source code that was set using the setGLSL() function. */
const std::string& getGLSL(); const std::string& getGLSL() { return _glsl; }
/** Returns whether the SPIR-V code has been set. */
bool hasGLSL() { return !_glsl.empty(); }
/** /**
* Converts GLSL code, set with setGLSL(), to SPIR-V code, which can be retrieved using getSPIRV(). * Converts GLSL code, set with setGLSL(), to SPIR-V code, which can be retrieved using getSPIRV().
@ -47,23 +56,23 @@ namespace mvk {
* The boolean flags indicate whether the original GLSL code and resulting SPIR-V code should * The boolean flags indicate whether the original GLSL code and resulting SPIR-V code should
* be logged to the result log of this converter. This can be useful during shader debugging. * be logged to the result log of this converter. This can be useful during shader debugging.
*/ */
bool convert(MVKShaderStage shaderStage, bool shouldLogGLSL, bool shouldLogSPIRV); bool convert(MVKGLSLConversionShaderStage shaderStage, bool shouldLogGLSL, bool shouldLogSPIRV);
/** Returns the SPIRV code most recently converted by the convert() function. */
const std::vector<uint32_t>& getSPIRV();
/** /**
* Returns whether the most recent conversion was successful. * Returns whether the most recent conversion was successful.
* *
* The initial value of this property is NO. It is set to YES upon successful conversion. * The initial value of this property is NO. It is set to YES upon successful conversion.
*/ */
bool getWasConverted(); bool wasConverted() { return _wasConverted; }
/** Returns the SPIRV code most recently converted by the convert() function. */
const std::vector<uint32_t>& getSPIRV() { return _spirv; }
/** /**
* Returns a human-readable log of the most recent conversion activity. * Returns a human-readable log of the most recent conversion activity.
* This may be empty if the conversion was successful. * This may be empty if the conversion was successful.
*/ */
const std::string& getResultLog(); const std::string& getResultLog() { return _resultLog; }
protected: protected:
void logMsg(const char* logMsg); void logMsg(const char* logMsg);

View File

@ -197,8 +197,6 @@ SPIRV_CROSS_NAMESPACE::CompilerMSL::Options::Platform getCompilerMSLPlatform(SPI
// Populates the entry point with info extracted from the SPRI-V compiler. // Populates the entry point with info extracted from the SPRI-V compiler.
void populateEntryPoint(SPIRVEntryPoint& entryPoint, SPIRV_CROSS_NAMESPACE::Compiler* pCompiler, SPIRVToMSLConverterOptions& options); void populateEntryPoint(SPIRVEntryPoint& entryPoint, SPIRV_CROSS_NAMESPACE::Compiler* pCompiler, SPIRVToMSLConverterOptions& options);
MVK_PUBLIC_SYMBOL void SPIRVToMSLConverter::setSPIRV(const vector<uint32_t>& spirv) { _spirv = spirv; }
MVK_PUBLIC_SYMBOL void SPIRVToMSLConverter::setSPIRV(const uint32_t* spirvCode, size_t length) { MVK_PUBLIC_SYMBOL void SPIRVToMSLConverter::setSPIRV(const uint32_t* spirvCode, size_t length) {
_spirv.clear(); // Clear for reuse _spirv.clear(); // Clear for reuse
_spirv.reserve(length); _spirv.reserve(length);
@ -207,8 +205,6 @@ MVK_PUBLIC_SYMBOL void SPIRVToMSLConverter::setSPIRV(const uint32_t* spirvCode,
} }
} }
MVK_PUBLIC_SYMBOL const vector<uint32_t>& SPIRVToMSLConverter::getSPIRV() { return _spirv; }
MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConverterContext& context, MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConverterContext& context,
bool shouldLogSPIRV, bool shouldLogSPIRV,
bool shouldLogMSL, bool shouldLogMSL,

View File

@ -225,7 +225,7 @@ namespace mvk {
public: public:
/** Sets the SPIRV code. */ /** Sets the SPIRV code. */
void setSPIRV(const std::vector<uint32_t>& spirv); void setSPIRV(const std::vector<uint32_t>& spirv) { _spirv = spirv; }
/** /**
* Sets the SPIRV code from the specified array of values. * Sets the SPIRV code from the specified array of values.
@ -234,7 +234,10 @@ namespace mvk {
void setSPIRV(const uint32_t* spirvCode, size_t length); void setSPIRV(const uint32_t* spirvCode, size_t length);
/** Returns a reference to the SPIRV code, set by one of the setSPIRV() functions. */ /** Returns a reference to the SPIRV code, set by one of the setSPIRV() functions. */
const std::vector<uint32_t>& getSPIRV(); const std::vector<uint32_t>& getSPIRV() { return _spirv; }
/** Returns whether the SPIR-V code has been set. */
bool hasSPIRV() { return !_spirv.empty(); }
/** /**
* Converts SPIR-V code, set using setSPIRV() to MSL code, which can be retrieved using getMSL(). * Converts SPIR-V code, set using setSPIRV() to MSL code, which can be retrieved using getMSL().
@ -248,6 +251,13 @@ namespace mvk {
bool shouldLogMSL = false, bool shouldLogMSL = false,
bool shouldLogGLSL = false); bool shouldLogGLSL = false);
/**
* Returns whether the most recent conversion was successful.
*
* The initial value of this property is NO. It is set to YES upon successful conversion.
*/
bool wasConverted() { return _wasConverted; }
/** /**
* Returns the Metal Shading Language source code most recently converted * Returns the Metal Shading Language source code most recently converted
* by the convert() function, or set directly using the setMSL() function. * by the convert() function, or set directly using the setMSL() function.
@ -257,13 +267,6 @@ namespace mvk {
/** Returns information about the shader entry point. */ /** Returns information about the shader entry point. */
const SPIRVEntryPoint& getEntryPoint() { return _entryPoint; } const SPIRVEntryPoint& getEntryPoint() { return _entryPoint; }
/**
* Returns whether the most recent conversion was successful.
*
* The initial value of this property is NO. It is set to YES upon successful conversion.
*/
bool getWasConverted() { return _wasConverted; }
/** /**
* Returns a human-readable log of the most recent conversion activity. * Returns a human-readable log of the most recent conversion activity.
* This may be empty if the conversion was successful. * This may be empty if the conversion was successful.

View File

@ -84,7 +84,7 @@ bool MoltenVKShaderConverterTool::processFile(string filePath) {
string pathExtn = pathExtension(absPath); string pathExtn = pathExtension(absPath);
if (_shouldReadGLSL && isGLSLFileExtension(pathExtn)) { if (_shouldReadGLSL && isGLSLFileExtension(pathExtn)) {
return convertGLSL(absPath, emptyPath, emptyPath, kMVKShaderStageAuto); return convertGLSL(absPath, emptyPath, emptyPath, kMVKGLSLConversionShaderStageAuto);
} else if (_shouldReadSPIRV && isSPIRVFileExtension(pathExtn)) { } else if (_shouldReadSPIRV && isSPIRVFileExtension(pathExtn)) {
return convertSPIRV(absPath, emptyPath); return convertSPIRV(absPath, emptyPath);
} }
@ -97,7 +97,7 @@ bool MoltenVKShaderConverterTool::processFile(string filePath) {
bool MoltenVKShaderConverterTool::convertGLSL(string& glslInFile, bool MoltenVKShaderConverterTool::convertGLSL(string& glslInFile,
string& spvOutFile, string& spvOutFile,
string& mslOutFile, string& mslOutFile,
MVKShaderStage shaderStage) { MVKGLSLConversionShaderStage shaderStage) {
string path; string path;
vector<char> fileContents; vector<char> fileContents;
string glslCode; string glslCode;
@ -120,11 +120,11 @@ bool MoltenVKShaderConverterTool::convertGLSL(string& glslInFile,
} }
glslCode.append(fileContents.begin(), fileContents.end()); glslCode.append(fileContents.begin(), fileContents.end());
if (shaderStage == kMVKShaderStageAuto) { if (shaderStage == kMVKGLSLConversionShaderStageAuto) {
string pathExtn = pathExtension(glslInFile); string pathExtn = pathExtension(glslInFile);
shaderStage = shaderStageFromFileExtension(pathExtn); shaderStage = shaderStageFromFileExtension(pathExtn);
} }
if (shaderStage == kMVKShaderStageAuto) { if (shaderStage == kMVKGLSLConversionShaderStageAuto) {
errMsg = "Could not determine shader type from GLSL file: " + absolutePath(path); errMsg = "Could not determine shader type from GLSL file: " + absolutePath(path);
log(errMsg.data()); log(errMsg.data());
return false; return false;
@ -254,11 +254,11 @@ bool MoltenVKShaderConverterTool::convertSPIRV(const vector<uint32_t>& spv,
} }
} }
MVKShaderStage MoltenVKShaderConverterTool::shaderStageFromFileExtension(string& pathExtension) { MVKGLSLConversionShaderStage MoltenVKShaderConverterTool::shaderStageFromFileExtension(string& pathExtension) {
for (auto& fx : _glslVtxFileExtns) { if (fx == pathExtension) { return kMVKShaderStageVertex; } } for (auto& fx : _glslVtxFileExtns) { if (fx == pathExtension) { return kMVKGLSLConversionShaderStageVertex; } }
for (auto& fx : _glslFragFileExtns) { if (fx == pathExtension) { return kMVKShaderStageFragment; } } for (auto& fx : _glslFragFileExtns) { if (fx == pathExtension) { return kMVKGLSLConversionShaderStageFragment; } }
for (auto& fx : _glslCompFileExtns) { if (fx == pathExtension) { return kMVKShaderStageCompute; } } for (auto& fx : _glslCompFileExtns) { if (fx == pathExtension) { return kMVKGLSLConversionShaderStageCompute; } }
return kMVKShaderStageAuto; return kMVKGLSLConversionShaderStageAuto;
} }
bool MoltenVKShaderConverterTool::isGLSLFileExtension(string& pathExtension) { bool MoltenVKShaderConverterTool::isGLSLFileExtension(string& pathExtension) {
@ -372,7 +372,7 @@ MoltenVKShaderConverterTool::MoltenVKShaderConverterTool(int argc, const char* a
extractTokens(_defaultCompShaderExtns, _glslCompFileExtns); extractTokens(_defaultCompShaderExtns, _glslCompFileExtns);
extractTokens(_defaultSPIRVShaderExtns, _spvFileExtns); extractTokens(_defaultSPIRVShaderExtns, _spvFileExtns);
_origPathExtnSep = "_"; _origPathExtnSep = "_";
_shaderStage = kMVKShaderStageAuto; _shaderStage = kMVKGLSLConversionShaderStageAuto;
_shouldUseDirectoryRecursion = false; _shouldUseDirectoryRecursion = false;
_shouldReadGLSL = false; _shouldReadGLSL = false;
_shouldReadSPIRV = false; _shouldReadSPIRV = false;
@ -482,13 +482,13 @@ bool MoltenVKShaderConverterTool::parseArgs(int argc, const char* argv[]) {
switch (shdrTypeStr.front()) { switch (shdrTypeStr.front()) {
case 'v': case 'v':
_shaderStage = kMVKShaderStageVertex; _shaderStage = kMVKGLSLConversionShaderStageVertex;
break; break;
case 'f': case 'f':
_shaderStage = kMVKShaderStageFragment; _shaderStage = kMVKGLSLConversionShaderStageFragment;
break; break;
case 'c': case 'c':
_shaderStage = kMVKShaderStageCompute; _shaderStage = kMVKGLSLConversionShaderStageCompute;
break; break;
default: default:
return false; return false;

View File

@ -64,13 +64,13 @@ namespace mvk {
MoltenVKShaderConverterTool(int argc, const char* argv[]); MoltenVKShaderConverterTool(int argc, const char* argv[]);
protected: protected:
MVKShaderStage shaderStageFromFileExtension(std::string& pathExtension); MVKGLSLConversionShaderStage shaderStageFromFileExtension(std::string& pathExtension);
bool isGLSLFileExtension(std::string& pathExtension); bool isGLSLFileExtension(std::string& pathExtension);
bool isSPIRVFileExtension(std::string& pathExtension); bool isSPIRVFileExtension(std::string& pathExtension);
bool convertGLSL(std::string& glslInFile, bool convertGLSL(std::string& glslInFile,
std::string& spvOutFile, std::string& spvOutFile,
std::string& mslOutFile, std::string& mslOutFile,
MVKShaderStage shaderStage); MVKGLSLConversionShaderStage shaderStage);
bool convertSPIRV(std::string& spvInFile, bool convertSPIRV(std::string& spvInFile,
std::string& mslOutFile); std::string& mslOutFile);
bool convertSPIRV(const std::vector<uint32_t>& spv, bool convertSPIRV(const std::vector<uint32_t>& spv,
@ -100,7 +100,7 @@ namespace mvk {
std::vector<std::string> _glslFragFileExtns; std::vector<std::string> _glslFragFileExtns;
std::vector<std::string> _glslCompFileExtns; std::vector<std::string> _glslCompFileExtns;
std::vector<std::string> _spvFileExtns; std::vector<std::string> _spvFileExtns;
MVKShaderStage _shaderStage; MVKGLSLConversionShaderStage _shaderStage;
MVKPerformanceTracker _glslConversionPerformance; MVKPerformanceTracker _glslConversionPerformance;
MVKPerformanceTracker _spvConversionPerformance; MVKPerformanceTracker _spvConversionPerformance;
uint32_t _mslVersionMajor; uint32_t _mslVersionMajor;