Add support for caching converted MSL shader code offline from pipeline cache
via vkGetPipelineCacheData(), vkCreatePipelineCache() & vkMergePipelineCaches(). Add the cereal serialization framework as a dependency. Update documentation. Update project settings to Xcode 9.3.
This commit is contained in:
parent
c45b47183e
commit
20c98e5e46
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,6 +21,7 @@ External/SPIRV-Tools
|
||||
External/SPIRV-Headers
|
||||
External/SPIRV-Cross
|
||||
External/VulkanSamples
|
||||
External/cereal
|
||||
|
||||
# Other source repository archive directories (protects when importing)
|
||||
.hg
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define __MVKStrings_h_ 1
|
||||
|
||||
#include <string>
|
||||
#include <streambuf>
|
||||
|
||||
namespace mvk {
|
||||
|
||||
@ -44,6 +45,26 @@ namespace mvk {
|
||||
return ( (startPos != std::string::npos) && (endPos != std::string::npos) ) ? s.substr(startPos, endPos + 1) : "";
|
||||
}
|
||||
|
||||
/** A memory-based stream buffer. */
|
||||
class membuf : public std::streambuf {
|
||||
public:
|
||||
membuf(char* p, size_t n) {
|
||||
setg(p, p, p + n);
|
||||
setp(p, p + n);
|
||||
}
|
||||
};
|
||||
|
||||
/** A character counting stream buffer. */
|
||||
class countbuf : public std::streambuf {
|
||||
public:
|
||||
size_t buffSize = 0;
|
||||
private:
|
||||
std::streamsize xsputn (const char* /* s */, std::streamsize n) override {
|
||||
buffSize += n;
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -623,7 +623,7 @@
|
||||
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
TargetAttributes = {
|
||||
A977BCBD1B66BB010067E5BF = {
|
||||
DevelopmentTeam = VU3TCKU48B;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -46,7 +45,6 @@
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -46,7 +45,6 @@
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -266,7 +266,7 @@
|
||||
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
TargetAttributes = {
|
||||
A9B53B0F1C3AC0BE00ABC6F6 = {
|
||||
DevelopmentTeam = VU3TCKU48B;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -46,7 +45,6 @@
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -46,7 +45,6 @@
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -355,7 +355,7 @@
|
||||
29B97313FDCFA39411CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
TargetAttributes = {
|
||||
A977BCBD1B66BB010067E5BF = {
|
||||
DevelopmentTeam = VU3TCKU48B;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -46,7 +45,6 @@
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -46,7 +45,6 @@
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -388,11 +388,33 @@ This section discusses various options for improving performance when using **Mo
|
||||
<a name="shader_load_time"></a>
|
||||
### Shader Loading Time
|
||||
|
||||
*Metal* supports pre-compiled shaders, which can improve shader loading and set-up performance,
|
||||
allowing you to reduce your scene loading time. See the [*Metal Shading Language* Shaders](#shaders)
|
||||
and [MoltenVKShaderConverter Shader Converter Tool](#shader_converter_tool) sections above for
|
||||
more information about how to use the `MoltenVKShaderConverter` tool to create and load pre-compiled
|
||||
*Metal* shaders into **MoltenVK**.
|
||||
A number of steps is require to load and compile *SPIR-V* shaders into a form that *Metal* can use.
|
||||
Although the overall process is fast, the slowest step involves converting shaders from *SPIR-V* to
|
||||
*MSL* source code format.
|
||||
|
||||
If you have a lot of shaders, you can dramatically improve shader loading time by using the standard
|
||||
*Vulkan pipeline cache* feature, to serialize shaders and store them in *MSL* form offline.
|
||||
Loading *MSL* shaders via the pipeline cache serializing mechanism can be significantly faster than
|
||||
converting from *SPIR-V* to *MSL* each time.
|
||||
|
||||
In *Vulkan*, pipeline cache serialization for offline storage is available through the
|
||||
`vkGetPipelineCacheData()` and `vkCreatePipelineCache()` functions. Loading the pipeline cache
|
||||
from offline storage at app start-up time can dramatically improve both shader loading performance,
|
||||
and performance glitches and hiccups during runtime code if shader loading is performed then.
|
||||
|
||||
When using pipeline caching, nothing changes about how you load *SPIR-V* shader code. **MoltenVK**
|
||||
automatically detects that the *SPIR-V* was previously converted to *MSL*, and stored offline via
|
||||
the *Vulkan* pipeline cache serialization mechanism, and does not invoke the relatively expensive
|
||||
step of converting the *SPIR-V* to *MSL* again.
|
||||
|
||||
As a second shader loading performance option, *Metal* also supports pre-compiled shaders, which
|
||||
can improve shader loading and set-up performance, allowing you to reduce your scene loading time.
|
||||
See the [*Metal Shading Language* Shaders](#shaders) and
|
||||
[MoltenVKShaderConverter Shader Converter Tool](#shader_converter_tool) sections above for more
|
||||
information about how to use the `MoltenVKShaderConverter` tool to create and load pre-compiled
|
||||
*Metal* shaders into **MoltenVK**. This behaviour is not standard *Vulkan* behaviour, and does not
|
||||
improve performance significantly. Your first choice should be to use offline storage of pipeline
|
||||
cache contents as described in the previous paragraphs.
|
||||
|
||||
|
||||
<a name="xcode_config"></a>
|
||||
|
39
External/README.md
vendored
39
External/README.md
vendored
@ -20,6 +20,7 @@ Table of Contents
|
||||
- [Adding the *SPIRV-Cross* Library to the *MoltenVKShaderConverter Xcode* Project](#add_spirv-cross)
|
||||
- [Adding the *SPIRV-Tools* Library to the *MoltenVKShaderConverter Xcode* Project](#add_spirv-tools)
|
||||
- [Adding the *glslang* Library to the *MoltenVKShaderConverter Xcode* Project](#add_glslang)
|
||||
- [Adding the *cereal* Library to the *MoltenVK Xcode* Project](#add_cereal)
|
||||
|
||||
|
||||
|
||||
@ -35,6 +36,7 @@ Fetching External Libraries
|
||||
- [*SPIRV-Tools*](https://github.com/KhronosGroup/SPIRV-Tools)
|
||||
- [*SPIRV-Headers*](https://github.com/KhronosGroup/SPIRV-Headers)
|
||||
- [*VulkanSamples*](https://github.com/brenwill/VulkanSamples)
|
||||
- [*cereal*](https://github.com/USCiLab/cereal)
|
||||
|
||||
These external open-source libraries are maintained in the `External` directory.
|
||||
To retrieve these libraries from their sources, run the `fetchDependencies`
|
||||
@ -75,9 +77,12 @@ determined as follows:
|
||||
|
||||
- **_SPIRV-Headers_**: automatically retrieved by the *glslang* repository.
|
||||
|
||||
You can update which version of the *SPIRV-Cross*, *VulkanSamples*, and
|
||||
*Vulkan-LoaderAndValidationLayers* libraries are retrieved, by changing the
|
||||
value held in the corresponding `*_repo_revision` file listed above.
|
||||
- **_cereal_**: a GitHub repository commit identifier found in the
|
||||
`External/cereal_repo_revision` file.
|
||||
|
||||
You can update which versions of the *SPIRV-Cross*, *VulkanSamples*,
|
||||
*Vulkan-LoaderAndValidationLayers*, or *cereal* libraries are retrieved,
|
||||
by changing the value held in the corresponding `*_repo_revision` file listed above.
|
||||
|
||||
The version of the *glslang*, *SPIRV-Tools*, and *SPIRV-Headers* libraries is
|
||||
automatically determined by the version of the *Vulkan-LoaderAndValidationLayers*
|
||||
@ -97,7 +102,7 @@ Adding the *SPIRV-Cross* Library to the *MoltenVKShaderConverter Xcode* Project
|
||||
|
||||
The `MoltenVKShaderConverter` *Xcode* project is already configured to use the *SPIRV-Cross*
|
||||
library. However, after updating the version of *SPIRV-Cross*, as described [above](#updating),
|
||||
if you encounter any linking errors, may need to re-add the *SPIRV-Cross* library to the
|
||||
if you encounter any building errors, you may need to re-add the *SPIRV-Cross* library to the
|
||||
`MoltenVKShaderConverter` *Xcode* project as follows:
|
||||
|
||||
1. In the *Project Navigator*, remove all of the files under the *Group* named
|
||||
@ -158,7 +163,7 @@ Adding the *SPIRV-Tools* Library to the *MoltenVKShaderConverter Xcode* Project
|
||||
|
||||
The `MoltenVKShaderConverter` *Xcode* project is already configured to use the *SPIRV-Tools*
|
||||
library. However, after updating the version of *SPIRV-Tools*, as described [above](#updating),
|
||||
if you encounter any linking errors, may need to re-add the *SPIRV-Tools* library to the
|
||||
if you encounter any building errors, you may need to re-add the *SPIRV-Tools* library to the
|
||||
`MoltenVKShaderConverter` *Xcode* project as follows:
|
||||
|
||||
1. In the *Project Navigator*, remove the *Group* named `source` from under the *Group* named
|
||||
@ -169,15 +174,17 @@ if you encounter any linking errors, may need to re-add the *SPIRV-Tools* librar
|
||||
_**Create groups**_ option, add the files to *both* the `MoltenVKSPIRVToMSLConverter-iOS`
|
||||
and `MoltenVKSPIRVToMSLConverter-macOS` targets, and click the ***Finish*** button.
|
||||
|
||||
3. In the *Project Navigator* panel, select your application's target, and open the
|
||||
*Build Settings* tab. Locate the build setting entry **Header Search Paths**
|
||||
(`HEADER_SEARCH_PATHS`) and add the following paths:
|
||||
3. In the *Project Navigator* panel, select the `MoltenVKShaderConverter` *Xcode* project, then select the
|
||||
`MoltenVKSPIRVToMSLConverter-macOS` target, and open the *Build Settings* tab. Locate the build setting
|
||||
entry **Header Search Paths** (`HEADER_SEARCH_PATHS`) and add the following paths:
|
||||
|
||||
"$(SRCROOT)/../External/glslang/External/spirv-tools/include"
|
||||
"$(SRCROOT)/../External/glslang/External/spirv-tools/source"
|
||||
"$(SRCROOT)/../External/glslang/External/spirv-tools/external/spirv-headers/include"
|
||||
"$(SRCROOT)/../External/glslang/build/External/spirv-tools"
|
||||
|
||||
4. Repeat *Step 3* for the `MoltenVKSPIRVToMSLConverter-iOS` target within the `MoltenVKShaderConverter` *Xcode* project
|
||||
|
||||
5. ***(Optional)*** To simplify the paths used within *Xcode* to reference the added files,
|
||||
perform the following steps:
|
||||
|
||||
@ -196,7 +203,7 @@ Adding the *glslang* Library to the *MoltenVKShaderConverter Xcode* Project
|
||||
|
||||
The `MoltenVKShaderConverter` *Xcode* project is already configured to use the *glslang*
|
||||
library. However, after updating the version of *glslang*, as described [above](#updating),
|
||||
if you encounter any linking errors, may need to re-add the *glslang* library to the
|
||||
if you encounter any building errors, you may need to re-add the *glslang* library to the
|
||||
`MoltenVKShaderConverter` *Xcode* project as follows:
|
||||
|
||||
1. In the *Project Navigator*, remove all *Groups* from under the *Group* named
|
||||
@ -229,3 +236,17 @@ if you encounter any linking errors, may need to re-add the *glslang* library to
|
||||
`glslang`, `OGLCompilersDLL`, and `SPIRV` directories added above.
|
||||
|
||||
|
||||
|
||||
<a name="add_cereal"></a>
|
||||
Adding the *cereal* Library to the *MoltenVK Xcode* Project
|
||||
-----------------------------------------------------------
|
||||
|
||||
The `MoltenVK` *Xcode* project is already configured to use the *cereal* library. However, after
|
||||
updating the version of *cereal*, as described [above](#updating), if you encounter any building
|
||||
errors, you may need to re-add the *cereal* library to the `MoltenVK` *Xcode* project as follows:
|
||||
|
||||
1. In the *Project Navigator* panel, select the `MoltenVK` *Xcode* project, then the `MoltenVK`
|
||||
project target, and open the *Build Settings* tab. Locate the build setting entry
|
||||
**Header Search Paths** (`HEADER_SEARCH_PATHS`) and add the following paths:
|
||||
|
||||
"$(SRCROOT)/../External/cereal/include"
|
||||
|
1
External/cereal_repo_revision
vendored
Normal file
1
External/cereal_repo_revision
vendored
Normal file
@ -0,0 +1 @@
|
||||
51cbda5f30e56c801c07fe3d3aba5d7fb9e6cca4
|
10
External/fetchDependencies
vendored
10
External/fetchDependencies
vendored
@ -48,6 +48,16 @@ echo
|
||||
V_LVL_NAME=Vulkan-LoaderAndValidationLayers
|
||||
GLSLANG_NAME=glslang
|
||||
|
||||
|
||||
# ----------------- Cereal -------------------
|
||||
|
||||
REPO_NAME=cereal
|
||||
REPO_URL="https://github.com/USCiLab/${REPO_NAME}.git"
|
||||
REPO_REV=$(cat "./${REPO_NAME}_repo_revision")
|
||||
|
||||
clone_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
|
||||
|
||||
|
||||
# ----------------- SPIRV-Cross -------------------
|
||||
|
||||
REPO_NAME=SPIRV-Cross
|
||||
|
@ -679,7 +679,7 @@
|
||||
A9F55D25198BE6A7004EC31B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "The Brenwill Workshop Ltd.";
|
||||
TargetAttributes = {
|
||||
A9B8EE091A98D796009C5A02 = {
|
||||
@ -969,6 +969,7 @@
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/include\"",
|
||||
"\"$(SRCROOT)/../MoltenVKShaderConverter\"",
|
||||
"\"$(SRCROOT)/../External/cereal/include\"",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MACH_O_TYPE = staticlib;
|
||||
@ -1026,6 +1027,7 @@
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"\"$(SRCROOT)/include\"",
|
||||
"\"$(SRCROOT)/../MoltenVKShaderConverter\"",
|
||||
"\"$(SRCROOT)/../External/cereal/include\"",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MACH_O_TYPE = staticlib;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -37,7 +36,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -37,7 +36,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -113,6 +113,9 @@ typedef struct {
|
||||
MVKShaderCompilationEventPerformance functionRetrieval; /** Retrieve a MTLFunction from a MTLLibrary. */
|
||||
MVKShaderCompilationEventPerformance functionSpecialization; /** Specialize a retrieved MTLFunction. */
|
||||
MVKShaderCompilationEventPerformance pipelineCompile; /** Compile MTLFunctions into a pipeline. */
|
||||
MVKShaderCompilationEventPerformance sizePipelineCache; /** Calculate the size of cache data required to write MSL to pipeline cache data stream. */
|
||||
MVKShaderCompilationEventPerformance writePipelineCache; /** Write MSL to pipeline cache data stream. */
|
||||
MVKShaderCompilationEventPerformance readPipelineCache; /** Read MSL from pipeline cache data stream. */
|
||||
} MVKShaderCompilationPerformance;
|
||||
|
||||
|
||||
|
@ -1328,7 +1328,7 @@ void MVKDevice::addShaderCompilationEventPerformanceImpl(MVKShaderCompilationEve
|
||||
double totalInterval = (shaderCompilationEvent.averageDuration * shaderCompilationEvent.count++) + currInterval;
|
||||
shaderCompilationEvent.averageDuration = totalInterval / shaderCompilationEvent.count;
|
||||
|
||||
MVKLogDebug("%s performance curr: %.3f ms, avg: %.3f ms, min: %.3f ms, max: %.3f ms, count: %d",
|
||||
MVKLogDebug("Shader building performance to %s curr: %.3f ms, avg: %.3f ms, min: %.3f ms, max: %.3f ms, count: %d",
|
||||
getShaderCompilationEventName(shaderCompilationEvent),
|
||||
currInterval,
|
||||
shaderCompilationEvent.averageDuration,
|
||||
@ -1338,14 +1338,17 @@ void MVKDevice::addShaderCompilationEventPerformanceImpl(MVKShaderCompilationEve
|
||||
}
|
||||
|
||||
const char* MVKDevice::getShaderCompilationEventName(MVKShaderCompilationEventPerformance& shaderCompilationEvent) {
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.hashShaderCode) { return "Hash shader code"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.spirvToMSL) { return "Convert SPIR-V to MSL source code"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.mslCompile) { return "Compile MSL source code into a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.mslLoad) { return "Load pre-compiled MSL code into a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.shaderLibraryFromCache) { return "Retrieve shader library from the cache."; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.functionRetrieval) { return "Retrieve a MTLFunction from a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.functionSpecialization) { return "Specialize a retrieved MTLFunction"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.pipelineCompile) { return "Compile MTLFunctions into a pipeline"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.hashShaderCode) { return "hash shader code"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.spirvToMSL) { return "convert SPIR-V to MSL source code"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.mslCompile) { return "compile MSL source code into a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.mslLoad) { return "load pre-compiled MSL code into a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.shaderLibraryFromCache) { return "retrieve shader library from the cache."; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.functionRetrieval) { return "retrieve a MTLFunction from a MTLLibrary"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.functionSpecialization) { return "specialize a retrieved MTLFunction"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.pipelineCompile) { return "compile MTLFunctions into a pipeline"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.sizePipelineCache) { return "calculate cache size required to write MSL to pipeline cache"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.writePipelineCache) { return "write MSL to pipeline cache"; }
|
||||
if (&shaderCompilationEvent == &_shaderCompilationPerformance.readPipelineCache) { return "read MSL from pipeline cache"; }
|
||||
return "Unknown shader compile event";
|
||||
}
|
||||
|
||||
@ -1406,6 +1409,8 @@ uint32_t MVKDevice::expandVisibilityResultMTLBuffer(uint32_t queryCount) {
|
||||
MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo* pCreateInfo) : _mvkConfig() {
|
||||
// MVKLogDebug("Creating MVKDevice. Elapsed time: %.6f ms.", mvkGetElapsedMilliseconds());
|
||||
|
||||
initPerformanceTracking();
|
||||
|
||||
_physicalDevice = physicalDevice;
|
||||
_pFeatures = &_physicalDevice->_features;
|
||||
_pMetalFeatures = &_physicalDevice->_metalFeatures;
|
||||
@ -1454,8 +1459,6 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
|
||||
}
|
||||
}
|
||||
|
||||
initPerformanceTracking();
|
||||
|
||||
MVKLogInfo("Created VkDevice to run on GPU %s", _pProperties->deviceName);
|
||||
}
|
||||
|
||||
@ -1474,6 +1477,9 @@ void MVKDevice::initPerformanceTracking() {
|
||||
_shaderCompilationPerformance.functionRetrieval = initPerf;
|
||||
_shaderCompilationPerformance.functionSpecialization = initPerf;
|
||||
_shaderCompilationPerformance.pipelineCompile = initPerf;
|
||||
_shaderCompilationPerformance.sizePipelineCache = initPerf;
|
||||
_shaderCompilationPerformance.writePipelineCache = initPerf;
|
||||
_shaderCompilationPerformance.readPipelineCache = initPerf;
|
||||
}
|
||||
|
||||
MVKDevice::~MVKDevice() {
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
@ -164,30 +165,32 @@ class MVKPipelineCache : public MVKBaseDeviceObject {
|
||||
public:
|
||||
|
||||
/**
|
||||
* If pData is not null, serializes at most pDataSize bytes of the contents of the cache
|
||||
* into that memory location, and returns the number of bytes serialized in pDataSize.
|
||||
* If pData is null, returns the number of bytes required to serialize the contents of
|
||||
* If pData is not null, serializes at most pDataSize bytes of the contents of the cache into that
|
||||
* memory location, and returns the number of bytes serialized in pDataSize. If pData is null,
|
||||
* returns the number of bytes required to serialize the contents of this pipeline cache.
|
||||
*/
|
||||
inline VkResult getData(size_t* pDataSize, void* pData) {
|
||||
*pDataSize = 0;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
VkResult writeData(size_t* pDataSize, void* pData);
|
||||
|
||||
/** Return a shader library from the specified shader context sourced from the specified shader module. */
|
||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConverterContext* pContext, MVKShaderModule* shaderModule);
|
||||
|
||||
/** Merges the contents of the specified number of pipeline caches into this cache. */
|
||||
inline VkResult mergePipelineCaches(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches) { return VK_SUCCESS; }
|
||||
VkResult mergePipelineCaches(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches);
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
/** Constructs an instance for the specified device. */
|
||||
MVKPipelineCache(MVKDevice* device, const VkPipelineCacheCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {}
|
||||
MVKPipelineCache(MVKDevice* device, const VkPipelineCacheCreateInfo* pCreateInfo);
|
||||
|
||||
~MVKPipelineCache() override;
|
||||
|
||||
protected:
|
||||
std::unordered_map<std::size_t, MVKShaderLibraryCache*> _shaderCacheByModuleHash;
|
||||
std::mutex _shaderCacheLock;
|
||||
MVKShaderLibraryCache* getShaderLibraryCache(MVKShaderModuleKey smKey);
|
||||
void readData(const VkPipelineCacheCreateInfo* pCreateInfo);
|
||||
void writeData(std::ostream& outstream, bool isCounting = false);
|
||||
void markDirty();
|
||||
|
||||
std::unordered_map<MVKShaderModuleKey, MVKShaderLibraryCache*> _shaderCache;
|
||||
size_t _dataSize = 0;
|
||||
std::mutex _shaderCacheLock;
|
||||
};
|
||||
|
@ -17,11 +17,18 @@
|
||||
*/
|
||||
|
||||
#include "MVKPipeline.h"
|
||||
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
|
||||
#include "MVKRenderPass.h"
|
||||
#include "MVKCommandBuffer.h"
|
||||
#include "MVKFoundation.h"
|
||||
#include "MVKOSExtensions.h"
|
||||
#include "MVKStrings.h"
|
||||
#include "mvk_datatypes.h"
|
||||
|
||||
#include <cereal/archives/binary.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
@ -453,20 +460,288 @@ MVKComputePipeline::~MVKComputePipeline() {
|
||||
MVKShaderLibrary* MVKPipelineCache::getShaderLibrary(SPIRVToMSLConverterContext* pContext, MVKShaderModule* shaderModule) {
|
||||
lock_guard<mutex> lock(_shaderCacheLock);
|
||||
|
||||
size_t smKey = shaderModule->getKey();
|
||||
MVKShaderLibraryCache* slCache = _shaderCacheByModuleHash[smKey];
|
||||
bool wasAdded = false;
|
||||
MVKShaderLibraryCache* slCache = getShaderLibraryCache(shaderModule->getKey());
|
||||
MVKShaderLibrary* shLib = slCache->getShaderLibrary(pContext, shaderModule, &wasAdded);
|
||||
if (wasAdded) { markDirty(); }
|
||||
return shLib;
|
||||
}
|
||||
|
||||
// Returns a shader library cache for the specified shader module key, creating it if necessary.
|
||||
MVKShaderLibraryCache* MVKPipelineCache::getShaderLibraryCache(MVKShaderModuleKey smKey) {
|
||||
MVKShaderLibraryCache* slCache = _shaderCache[smKey];
|
||||
if ( !slCache ) {
|
||||
slCache = new MVKShaderLibraryCache(_device);
|
||||
_shaderCacheByModuleHash[smKey] = slCache;
|
||||
_shaderCache[smKey] = slCache;
|
||||
}
|
||||
return slCache;
|
||||
}
|
||||
|
||||
return slCache->getShaderLibrary(pContext, shaderModule);
|
||||
|
||||
#pragma mark Streaming pipeline cache to and from offline memory
|
||||
|
||||
static uint32_t kDataHeaderSize = (sizeof(uint32_t) * 4) + VK_UUID_SIZE;
|
||||
|
||||
// Entry type markers to be inserted into data stream
|
||||
typedef enum {
|
||||
MVKPipelineCacheEntryTypeEOF = 0,
|
||||
MVKPipelineCacheEntryTypeShaderLibrary = 1,
|
||||
} MVKPipelineCacheEntryType;
|
||||
|
||||
// Ceral archive definitions
|
||||
namespace mvk {
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive, SPIRVEntryPoint& ep) {
|
||||
archive(ep.mtlFunctionName,
|
||||
ep.workgroupSize.width,
|
||||
ep.workgroupSize.height,
|
||||
ep.workgroupSize.depth,
|
||||
ep.workgroupSizeId.width,
|
||||
ep.workgroupSizeId.height,
|
||||
ep.workgroupSizeId.depth,
|
||||
ep.workgroupSizeId.constant);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive, SPIRVToMSLConverterOptions& opt) {
|
||||
archive(opt.entryPointName,
|
||||
opt.entryPointStage,
|
||||
opt.mslVersion,
|
||||
opt.shouldFlipVertexY,
|
||||
opt.isRenderingPoints);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive, MSLVertexAttribute& va) {
|
||||
archive(va.location,
|
||||
va.mslBuffer,
|
||||
va.mslOffset,
|
||||
va.mslStride,
|
||||
va.isPerInstance,
|
||||
va.isUsedByShader);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive, MSLResourceBinding& rb) {
|
||||
archive(rb.stage,
|
||||
rb.descriptorSet,
|
||||
rb.binding,
|
||||
rb.mslBuffer,
|
||||
rb.mslTexture,
|
||||
rb.mslSampler,
|
||||
rb.isUsedByShader);
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive, SPIRVToMSLConverterContext& ctx) {
|
||||
archive(ctx.options, ctx.vertexAttributes, ctx.resourceBindings);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive, MVKShaderModuleKey& k) {
|
||||
archive(k.codeSize, k.codeHash);
|
||||
}
|
||||
|
||||
// Helper class to iterate through the shader libraries in a shader library cache in order to serialize them.
|
||||
// Needs to support input of null shader library cache.
|
||||
class MVKShaderCacheIterator : MVKBaseObject {
|
||||
protected:
|
||||
friend MVKPipelineCache;
|
||||
|
||||
bool next() { return (++_index < (_pSLCache ? _pSLCache->_shaderLibraries.size() : 0)); }
|
||||
SPIRVToMSLConverterContext& getShaderContext() { return _pSLCache->_shaderLibraries[_index].first; }
|
||||
std::string& getMSL() { return _pSLCache->_shaderLibraries[_index].second->_msl; }
|
||||
SPIRVEntryPoint& getEntryPoint() { return _pSLCache->_shaderLibraries[_index].second->_entryPoint; }
|
||||
MVKShaderCacheIterator(MVKShaderLibraryCache* pSLCache) : _pSLCache(pSLCache) {}
|
||||
|
||||
MVKShaderLibraryCache* _pSLCache;
|
||||
size_t _count = 0;
|
||||
int32_t _index = -1;
|
||||
};
|
||||
|
||||
// If pData is not null, serializes at most pDataSize bytes of the contents of the cache into that
|
||||
// memory location, and returns the number of bytes serialized in pDataSize. If pData is null,
|
||||
// returns the number of bytes required to serialize the contents of this pipeline cache.
|
||||
// This is the compliment of the readData() function. The two must be kept aligned.
|
||||
VkResult MVKPipelineCache::writeData(size_t* pDataSize, void* pData) {
|
||||
lock_guard<mutex> lock(_shaderCacheLock);
|
||||
|
||||
try {
|
||||
|
||||
if ( !pDataSize ) { return VK_SUCCESS; }
|
||||
|
||||
if (pData) {
|
||||
if (*pDataSize >= _dataSize) {
|
||||
mvk::membuf mb((char*)pData, _dataSize);
|
||||
ostream outStream(&mb);
|
||||
writeData(outStream);
|
||||
*pDataSize = _dataSize;
|
||||
return VK_SUCCESS;
|
||||
} else {
|
||||
*pDataSize = 0;
|
||||
return VK_INCOMPLETE;
|
||||
}
|
||||
} else {
|
||||
if (_dataSize == 0) {
|
||||
mvk::countbuf cb;
|
||||
ostream outStream(&cb);
|
||||
writeData(outStream, true);
|
||||
_dataSize = cb.buffSize;
|
||||
}
|
||||
*pDataSize = _dataSize;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
} catch (cereal::Exception& ex) {
|
||||
*pDataSize = 0;
|
||||
return mvkNotifyErrorWithText(VK_INCOMPLETE, "Error writing pipeline cache data: %s", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
// Serializes the data in this cache to a stream
|
||||
void MVKPipelineCache::writeData(ostream& outstream, bool isCounting) {
|
||||
|
||||
MVKShaderCompilationEventPerformance& shaderCompilationEvent = isCounting
|
||||
? _device->_shaderCompilationPerformance.sizePipelineCache
|
||||
: _device->_shaderCompilationPerformance.writePipelineCache;
|
||||
|
||||
uint32_t cacheEntryType;
|
||||
cereal::BinaryOutputArchive writer(outstream);
|
||||
|
||||
// Write the data header...after ensuring correct byte-order.
|
||||
const VkPhysicalDeviceProperties* pDevProps = _device->_pProperties;
|
||||
writer(NSSwapHostIntToLittle(kDataHeaderSize));
|
||||
writer(NSSwapHostIntToLittle(VK_PIPELINE_CACHE_HEADER_VERSION_ONE));
|
||||
writer(NSSwapHostIntToLittle(pDevProps->vendorID));
|
||||
writer(NSSwapHostIntToLittle(pDevProps->deviceID));
|
||||
writer(pDevProps->pipelineCacheUUID);
|
||||
|
||||
// Shader libraries
|
||||
// Output a cache entry for each shader library, including the shader module key in each entry.
|
||||
cacheEntryType = MVKPipelineCacheEntryTypeShaderLibrary;
|
||||
for (auto& scPair : _shaderCache) {
|
||||
MVKShaderModuleKey smKey = scPair.first;
|
||||
MVKShaderCacheIterator cacheIter(scPair.second);
|
||||
while (cacheIter.next()) {
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
writer(cacheEntryType);
|
||||
writer(smKey);
|
||||
writer(cacheIter.getShaderContext());
|
||||
writer(cacheIter.getEntryPoint());
|
||||
writer(cacheIter.getMSL());
|
||||
_device->addShaderCompilationEventPerformance(shaderCompilationEvent, startTime);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the end of the archive
|
||||
cacheEntryType = MVKPipelineCacheEntryTypeEOF;
|
||||
writer(cacheEntryType);
|
||||
}
|
||||
|
||||
// Loads any data indicated by the creation info.
|
||||
// This is the compliment of the writeData() function. The two must be kept aligned.
|
||||
void MVKPipelineCache::readData(const VkPipelineCacheCreateInfo* pCreateInfo) {
|
||||
try {
|
||||
|
||||
size_t byteCount = pCreateInfo->initialDataSize;
|
||||
uint32_t cacheEntryType;
|
||||
|
||||
// Must be able to read the header and at least one cache entry type.
|
||||
if (byteCount < kDataHeaderSize + sizeof(cacheEntryType)) { return; }
|
||||
|
||||
mvk::membuf mb((char*)pCreateInfo->pInitialData, byteCount);
|
||||
istream inStream(&mb);
|
||||
cereal::BinaryInputArchive reader(inStream);
|
||||
|
||||
// Read the data header...and ensure correct byte-order.
|
||||
uint32_t hdrComponent;
|
||||
uint8_t pcUUID[VK_UUID_SIZE];
|
||||
const VkPhysicalDeviceProperties* pDevProps = _device->_pProperties;
|
||||
|
||||
reader(hdrComponent); // Header size
|
||||
if (NSSwapLittleIntToHost(hdrComponent) != kDataHeaderSize) { return; }
|
||||
|
||||
reader(hdrComponent); // Header version
|
||||
if (NSSwapLittleIntToHost(hdrComponent) != VK_PIPELINE_CACHE_HEADER_VERSION_ONE) { return; }
|
||||
|
||||
reader(hdrComponent); // Vendor ID
|
||||
if (NSSwapLittleIntToHost(hdrComponent) != pDevProps->vendorID) { return; }
|
||||
|
||||
reader(hdrComponent); // Device ID
|
||||
if (NSSwapLittleIntToHost(hdrComponent) != pDevProps->deviceID) { return; }
|
||||
|
||||
reader(pcUUID); // Pipeline cache UUID
|
||||
if (memcmp(pcUUID, pDevProps->pipelineCacheUUID, VK_UUID_SIZE) != 0) { return; }
|
||||
|
||||
bool done = false;
|
||||
while ( !done ) {
|
||||
reader(cacheEntryType);
|
||||
switch (cacheEntryType) {
|
||||
case MVKPipelineCacheEntryTypeShaderLibrary: {
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
|
||||
MVKShaderModuleKey smKey;
|
||||
reader(smKey);
|
||||
|
||||
SPIRVToMSLConverterContext shaderContext;
|
||||
reader(shaderContext);
|
||||
|
||||
SPIRVEntryPoint entryPoint;
|
||||
reader(entryPoint);
|
||||
|
||||
string msl;
|
||||
reader(msl);
|
||||
|
||||
// Add the shader library to the staging cache.
|
||||
MVKShaderLibraryCache* slCache = getShaderLibraryCache(smKey);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.readPipelineCache, startTime);
|
||||
slCache->addShaderLibrary(&shaderContext, msl, entryPoint);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (cereal::Exception& ex) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_SUCCESS, "Error reading pipeline cache data: %s", ex.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the cache as dirty, so that existing streaming info is released
|
||||
void MVKPipelineCache::markDirty() {
|
||||
_dataSize = 0;
|
||||
}
|
||||
|
||||
VkResult MVKPipelineCache::mergePipelineCaches(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches) {
|
||||
for (uint32_t srcIdx = 0; srcIdx < srcCacheCount; srcIdx++) {
|
||||
MVKPipelineCache* srcPLC = (MVKPipelineCache*)pSrcCaches[srcIdx];
|
||||
for (auto& srcPair : srcPLC->_shaderCache) {
|
||||
getShaderLibraryCache(srcPair.first)->merge(srcPair.second);
|
||||
}
|
||||
}
|
||||
markDirty();
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
MVKPipelineCache::MVKPipelineCache(MVKDevice* device, const VkPipelineCacheCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device) {
|
||||
readData(pCreateInfo);
|
||||
}
|
||||
|
||||
MVKPipelineCache::~MVKPipelineCache() {
|
||||
for (auto& pair : _shaderCacheByModuleHash) { delete pair.second; }
|
||||
_shaderCacheByModuleHash.clear();
|
||||
for (auto& pair : _shaderCache) { delete pair.second; }
|
||||
_shaderCache.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
class MVKPipelineCache;
|
||||
class MVKShaderCacheIterator;
|
||||
|
||||
using namespace mvk;
|
||||
|
||||
@ -50,7 +51,7 @@ public:
|
||||
MVKMTLFunction getMTLFunction(const VkSpecializationInfo* pSpecializationInfo);
|
||||
|
||||
/** Constructs an instance from the specified MSL source code. */
|
||||
MVKShaderLibrary(MVKDevice* device, const char* mslSourceCode, const SPIRVEntryPoint& entryPoint);
|
||||
MVKShaderLibrary(MVKDevice* device, const std::string& mslSourceCode, const SPIRVEntryPoint& entryPoint);
|
||||
|
||||
/** Constructs an instance from the specified compiled MSL code data. */
|
||||
MVKShaderLibrary(MVKDevice* device,
|
||||
@ -60,11 +61,14 @@ public:
|
||||
~MVKShaderLibrary() override;
|
||||
|
||||
protected:
|
||||
friend MVKShaderCacheIterator;
|
||||
|
||||
void handleCompilationError(NSError* err, const char* opDesc);
|
||||
MTLFunctionConstant* getFunctionConstant(NSArray<MTLFunctionConstant*>* mtlFCs, NSUInteger mtlFCID);
|
||||
|
||||
id<MTLLibrary> _mtlLibrary;
|
||||
SPIRVEntryPoint _entryPoint;
|
||||
std::string _msl;
|
||||
};
|
||||
|
||||
|
||||
@ -76,21 +80,32 @@ class MVKShaderLibraryCache : public MVKBaseDeviceObject {
|
||||
|
||||
public:
|
||||
|
||||
/** Return a shader library from the specified shader context sourced from the specified shader module. */
|
||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConverterContext* pContext, MVKShaderModule* shaderModule);
|
||||
/**
|
||||
* Returns a shader library from the specified shader context sourced from the specified shader module,
|
||||
* lazily creating the shader library from source code in the shader module, if needed.
|
||||
*
|
||||
* If pWasAdded is not nil, this function will set it to true if a new shader library was created,
|
||||
* and to false if an existing shader library was found and returned.
|
||||
*/
|
||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConverterContext* pContext,
|
||||
MVKShaderModule* shaderModule,
|
||||
bool* pWasAdded = nullptr);
|
||||
|
||||
MVKShaderLibraryCache(MVKDevice* device) : MVKBaseDeviceObject(device) {};
|
||||
|
||||
~MVKShaderLibraryCache() override;
|
||||
|
||||
protected:
|
||||
friend MVKShaderCacheIterator;
|
||||
friend MVKPipelineCache;
|
||||
|
||||
MVKShaderLibrary* findShaderLibrary(SPIRVToMSLConverterContext* pContext);
|
||||
MVKShaderLibrary* addShaderLibrary(SPIRVToMSLConverterContext* pContext,
|
||||
const char* mslSourceCode,
|
||||
const std::string& mslSourceCode,
|
||||
const SPIRVEntryPoint& entryPoint);
|
||||
void merge(MVKShaderLibraryCache* other);
|
||||
|
||||
std::mutex _accessLock;
|
||||
std::size_t _shaderModuleHash;
|
||||
std::vector<std::pair<SPIRVToMSLConverterContext, MVKShaderLibrary*>> _shaderLibraries;
|
||||
};
|
||||
|
||||
@ -98,6 +113,30 @@ protected:
|
||||
#pragma mark -
|
||||
#pragma mark MVKShaderModule
|
||||
|
||||
typedef struct MVKShaderModuleKey_t {
|
||||
std::size_t codeSize;
|
||||
std::size_t codeHash;
|
||||
|
||||
bool operator==(const MVKShaderModuleKey_t& rhs) const {
|
||||
return ((codeSize == rhs.codeSize) && (codeHash == rhs.codeHash));
|
||||
}
|
||||
MVKShaderModuleKey_t(std::size_t codeSize, std::size_t codeHash) : codeSize(codeSize), codeHash(codeHash) {}
|
||||
MVKShaderModuleKey_t() : MVKShaderModuleKey_t(0, 0) {}
|
||||
} MVKShaderModuleKey;
|
||||
|
||||
/**
|
||||
* Hash structure implementation for MVKShaderModuleKey in std namespace,
|
||||
* so MVKShaderModuleKey can be used as a key in a std::map and std::unordered_map.
|
||||
*/
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<MVKShaderModuleKey> {
|
||||
std::size_t operator()(const MVKShaderModuleKey& k) const {
|
||||
return k.codeHash;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** Represents a Vulkan shader module. */
|
||||
class MVKShaderModule : public MVKBaseDeviceObject {
|
||||
|
||||
@ -111,25 +150,30 @@ public:
|
||||
bool convert(SPIRVToMSLConverterContext* pContext);
|
||||
|
||||
/**
|
||||
* Returns the Metal Shading Language source code most recently converted
|
||||
* by the convert() function, or set directly using the setMSL() function.
|
||||
* Returns the Metal Shading Language source code as converted by the most recent
|
||||
* call to convert() function, or set directly using the setMSL() function.
|
||||
*/
|
||||
inline const std::string& getMSL() { return _converter.getMSL(); }
|
||||
|
||||
/** Returns information about the shader entry point. */
|
||||
/**
|
||||
* Returns information about the shader entry point as converted by the most recent
|
||||
* call to convert() function, or set directly using the setMSL() function.
|
||||
*/
|
||||
inline const SPIRVEntryPoint& getEntryPoint() { return _converter.getEntryPoint(); }
|
||||
|
||||
/** Returns a key as a means of identifying this shader module in a pipeline cache. */
|
||||
inline std::size_t getKey() { return _key; }
|
||||
inline MVKShaderModuleKey getKey() { return _key; }
|
||||
|
||||
MVKShaderModule(MVKDevice* device, const VkShaderModuleCreateInfo* pCreateInfo);
|
||||
|
||||
~MVKShaderModule() override;
|
||||
|
||||
protected:
|
||||
friend MVKShaderCacheIterator;
|
||||
|
||||
MVKShaderLibraryCache _shaderLibraryCache;
|
||||
SPIRVToMSLConverter _converter;
|
||||
MVKShaderLibrary* _defaultLibrary;
|
||||
std::size_t _key;
|
||||
MVKShaderModuleKey _key;
|
||||
std::mutex _accessLock;
|
||||
};
|
||||
|
@ -120,12 +120,12 @@ MTLFunctionConstant* MVKShaderLibrary::getFunctionConstant(NSArray<MTLFunctionCo
|
||||
return nil;
|
||||
}
|
||||
|
||||
MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device, const char* mslSourceCode, const SPIRVEntryPoint& entryPoint) : MVKBaseDeviceObject(device) {
|
||||
MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device, const string& mslSourceCode, const SPIRVEntryPoint& entryPoint) : MVKBaseDeviceObject(device) {
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
@autoreleasepool {
|
||||
MTLCompileOptions* options = [[MTLCompileOptions new] autorelease]; // TODO: what compile options apply?
|
||||
NSError* err = nil;
|
||||
_mtlLibrary = [getMTLDevice() newLibraryWithSource: @(mslSourceCode)
|
||||
_mtlLibrary = [getMTLDevice() newLibraryWithSource: @(mslSourceCode.c_str())
|
||||
options: options
|
||||
error: &err]; // retained
|
||||
handleCompilationError(err, "Shader module compilation");
|
||||
@ -133,6 +133,7 @@ MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device, const char* mslSourceCode,
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.mslCompile, startTime);
|
||||
|
||||
_entryPoint = entryPoint;
|
||||
_msl = mslSourceCode;
|
||||
}
|
||||
|
||||
MVKShaderLibrary::MVKShaderLibrary(MVKDevice* device,
|
||||
@ -178,13 +179,19 @@ MVKShaderLibrary::~MVKShaderLibrary() {
|
||||
#pragma mark MVKShaderLibraryCache
|
||||
|
||||
MVKShaderLibrary* MVKShaderLibraryCache::getShaderLibrary(SPIRVToMSLConverterContext* pContext,
|
||||
MVKShaderModule* shaderModule) {
|
||||
MVKShaderModule* shaderModule,
|
||||
bool* pWasAdded) {
|
||||
bool wasAdded = false;
|
||||
MVKShaderLibrary* shLib = findShaderLibrary(pContext);
|
||||
if ( !shLib ) {
|
||||
if (shaderModule->convert(pContext)) {
|
||||
shLib = addShaderLibrary(pContext, shaderModule->getMSL().c_str(), shaderModule->getEntryPoint());
|
||||
shLib = addShaderLibrary(pContext, shaderModule->getMSL(), shaderModule->getEntryPoint());
|
||||
wasAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pWasAdded) { *pWasAdded = wasAdded; }
|
||||
|
||||
return shLib;
|
||||
}
|
||||
|
||||
@ -200,15 +207,25 @@ MVKShaderLibrary* MVKShaderLibraryCache::findShaderLibrary(SPIRVToMSLConverterCo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Adds and returns a new shader library configured from the specified context. */
|
||||
// Adds and returns a new shader library configured from the specified context.
|
||||
MVKShaderLibrary* MVKShaderLibraryCache::addShaderLibrary(SPIRVToMSLConverterContext* pContext,
|
||||
const char* mslSourceCode,
|
||||
const string& mslSourceCode,
|
||||
const SPIRVEntryPoint& entryPoint) {
|
||||
MVKShaderLibrary* shLib = new MVKShaderLibrary(_device, mslSourceCode, entryPoint);
|
||||
_shaderLibraries.push_back(pair<SPIRVToMSLConverterContext, MVKShaderLibrary*>(*pContext, shLib));
|
||||
return shLib;
|
||||
}
|
||||
|
||||
// Merge another shader library cache with this one. Handle null input.
|
||||
void MVKShaderLibraryCache::merge(MVKShaderLibraryCache* other) {
|
||||
if ( !other ) { return; }
|
||||
for (auto& otherPair : other->_shaderLibraries) {
|
||||
if ( !findShaderLibrary(&otherPair.first) ) {
|
||||
_shaderLibraries.push_back(otherPair);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MVKShaderLibraryCache::~MVKShaderLibraryCache() {
|
||||
for (auto& slPair : _shaderLibraries) { delete slPair.second; }
|
||||
}
|
||||
@ -225,10 +242,8 @@ MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConverterContext* pCont
|
||||
if ( !mvkLib ) {
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
if (pipelineCache) {
|
||||
MVKLogDebug("Retrieving shader from pipeline cache.");
|
||||
mvkLib = pipelineCache->getShaderLibrary(pContext, this);
|
||||
} else {
|
||||
MVKLogDebug("Retrieving shader from shader module.");
|
||||
mvkLib = _shaderLibraryCache.getShaderLibrary(pContext, this);
|
||||
}
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.shaderLibraryFromCache, startTime);
|
||||
@ -255,10 +270,11 @@ bool MVKShaderModule::convert(SPIRVToMSLConverterContext* pContext) {
|
||||
#pragma mark Construction
|
||||
|
||||
MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
const VkShaderModuleCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device),
|
||||
_shaderLibraryCache(device) {
|
||||
const VkShaderModuleCreateInfo* pCreateInfo) : MVKBaseDeviceObject(device), _shaderLibraryCache(device) {
|
||||
|
||||
_defaultLibrary = nullptr;
|
||||
|
||||
|
||||
size_t codeSize = pCreateInfo->codeSize;
|
||||
|
||||
// Ensure something is there.
|
||||
@ -267,7 +283,7 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
return;
|
||||
}
|
||||
|
||||
_key = mvkHash(&pCreateInfo->codeSize, 1);
|
||||
size_t codeHash = 0;
|
||||
|
||||
// Retrieve the magic number to determine what type of shader code has been loaded.
|
||||
uint32_t magicNum = *pCreateInfo->pCode;
|
||||
@ -276,7 +292,7 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
size_t spvCount = (pCreateInfo->codeSize + 3) >> 2; // Round up if byte length not exactly on uint32_t boundary
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
_key = mvkHash(pCreateInfo->pCode, spvCount, _key);
|
||||
codeHash = mvkHash(pCreateInfo->pCode, spvCount);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
_converter.setSPIRV(pCreateInfo->pCode, spvCount);
|
||||
@ -289,8 +305,8 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize;
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
_key = mvkHash(&magicNum, 1, _key);
|
||||
_key = mvkHash(pMSLCode, mslCodeLen, _key);
|
||||
codeHash = mvkHash(&magicNum, 1);
|
||||
codeHash = mvkHash(pMSLCode, mslCodeLen, codeHash);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
_converter.setMSL(pMSLCode, nullptr);
|
||||
@ -304,8 +320,8 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
size_t mslCodeLen = pCreateInfo->codeSize - hdrSize;
|
||||
|
||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||
_key = mvkHash(&magicNum, 1, _key);
|
||||
_key = mvkHash(pMSLCode, mslCodeLen, _key);
|
||||
codeHash = mvkHash(&magicNum, 1);
|
||||
codeHash = mvkHash(pMSLCode, mslCodeLen, codeHash);
|
||||
_device->addShaderCompilationEventPerformance(_device->_shaderCompilationPerformance.hashShaderCode, startTime);
|
||||
|
||||
_defaultLibrary = new MVKShaderLibrary(_device, (void*)(pMSLCode), mslCodeLen);
|
||||
@ -316,6 +332,8 @@ MVKShaderModule::MVKShaderModule(MVKDevice* device,
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_FORMAT_NOT_SUPPORTED, "SPIR-V contains invalid magic number %x.", magicNum));
|
||||
break;
|
||||
}
|
||||
|
||||
_key = MVKShaderModuleKey(codeSize, codeHash);
|
||||
}
|
||||
|
||||
MVKShaderModule::~MVKShaderModule() {
|
||||
|
@ -674,7 +674,7 @@ MVK_PUBLIC_SYMBOL VkResult vkGetPipelineCacheData(
|
||||
void* pData) {
|
||||
|
||||
MVKPipelineCache* mvkPLC = (MVKPipelineCache*)pipelineCache;
|
||||
return mvkPLC->getData(pDataSize, pData);
|
||||
return mvkPLC->writeData(pDataSize, pData);
|
||||
}
|
||||
|
||||
MVK_PUBLIC_SYMBOL VkResult vkMergePipelineCaches(
|
||||
|
@ -143,6 +143,7 @@
|
||||
A9AD67D22054E2D700ED3C08 /* Vulkan-LoaderAndValidationLayers_repo_revision */ = {isa = PBXFileReference; lastKnownFileType = text; path = "Vulkan-LoaderAndValidationLayers_repo_revision"; sourceTree = "<group>"; };
|
||||
A9AD67D32054E2D700ED3C08 /* SPIRV-Cross_repo_revision */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SPIRV-Cross_repo_revision"; sourceTree = "<group>"; };
|
||||
A9AD67E92055D8A600ED3C08 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
A9EE46412065766C00193200 /* cereal_repo_revision */ = {isa = PBXFileReference; lastKnownFileType = text; path = cereal_repo_revision; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@ -181,6 +182,7 @@
|
||||
children = (
|
||||
A9AD67E92055D8A600ED3C08 /* README.md */,
|
||||
A943100220546CDD00F5CF87 /* fetchDependencies */,
|
||||
A9EE46412065766C00193200 /* cereal_repo_revision */,
|
||||
A9AD67D32054E2D700ED3C08 /* SPIRV-Cross_repo_revision */,
|
||||
A9AD67D22054E2D700ED3C08 /* Vulkan-LoaderAndValidationLayers_repo_revision */,
|
||||
A9AD67D12054E2D700ED3C08 /* VulkanSamples_repo_revision */,
|
||||
@ -206,7 +208,7 @@
|
||||
A90B2B1D1A9B6170008EE819 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
TargetAttributes = {
|
||||
A9FEADBC1F3517480010240E = {
|
||||
DevelopmentTeam = VU3TCKU48B;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -38,7 +37,6 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
disableMainThreadChecker = "YES"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -38,7 +37,6 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
disableMainThreadChecker = "YES"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -2209,7 +2209,7 @@
|
||||
A9F55D25198BE6A7004EC31B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "The Brenwill Workshop Ltd.";
|
||||
TargetAttributes = {
|
||||
A9092A8C1A81717B00051823 = {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -37,7 +36,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -37,7 +36,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -37,7 +36,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -37,7 +36,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0920"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@ -26,7 +26,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
@ -46,7 +45,6 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
@ -74,19 +72,19 @@
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-gi"
|
||||
isEnabled = "YES">
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "/Users/bill/Documents/Dev/iOSProjects/Molten/MoltenVK-bh/External/SPIRV-Cross/shaders-msl/comp/struct-nested.comp"
|
||||
isEnabled = "YES">
|
||||
argument = "/Users/bill/Documents/Dev/iOSProjects/Molten/Support/2018/MVK_Issue_112/bad_attrs.vert"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-si"
|
||||
isEnabled = "NO">
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "/Users/bill/Documents/Dev/iOSProjects/Molten/Support/Valve/Dota2/shader-issues/sample_mask/sample_mask.spv"
|
||||
isEnabled = "NO">
|
||||
argument = "/Users/bill/Documents/Dev/iOSProjects/Molten/Support/2018/MVK_Issue_112/second/vert_bin.spv"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-mo"
|
||||
|
Loading…
x
Reference in New Issue
Block a user