Merge pull request #764 from billhollings/master

 Support additional capabilities in 1D images, including rendering, clearing, and mipmaps.
diff --git a/Demos/LunarG-VulkanSamples/API-Samples/API-Samples.xcodeproj/project.pbxproj b/Demos/LunarG-VulkanSamples/API-Samples/API-Samples.xcodeproj/project.pbxproj
index 26b8d52..1fd9110 100644
--- a/Demos/LunarG-VulkanSamples/API-Samples/API-Samples.xcodeproj/project.pbxproj
+++ b/Demos/LunarG-VulkanSamples/API-Samples/API-Samples.xcodeproj/project.pbxproj
@@ -546,11 +546,6 @@
 			isa = PBXProject;
 			attributes = {
 				LastUpgradeCheck = 1110;
-				TargetAttributes = {
-					A977BCBD1B66BB010067E5BF = {
-						DevelopmentTeam = VU3TCKU48B;
-					};
-				};
 			};
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "API-Samples" */;
 			compatibilityVersion = "Xcode 8.0";
diff --git a/Demos/LunarG-VulkanSamples/Cube/Cube.xcodeproj/project.pbxproj b/Demos/LunarG-VulkanSamples/Cube/Cube.xcodeproj/project.pbxproj
index 940a572..f61eb24 100644
--- a/Demos/LunarG-VulkanSamples/Cube/Cube.xcodeproj/project.pbxproj
+++ b/Demos/LunarG-VulkanSamples/Cube/Cube.xcodeproj/project.pbxproj
@@ -235,11 +235,6 @@
 			isa = PBXProject;
 			attributes = {
 				LastUpgradeCheck = 1110;
-				TargetAttributes = {
-					A9B53B0F1C3AC0BE00ABC6F6 = {
-						DevelopmentTeam = VU3TCKU48B;
-					};
-				};
 			};
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Cube" */;
 			compatibilityVersion = "Xcode 8.0";
diff --git a/Demos/LunarG-VulkanSamples/Hologram/Hologram.xcodeproj/project.pbxproj b/Demos/LunarG-VulkanSamples/Hologram/Hologram.xcodeproj/project.pbxproj
index cefd96d..90d5f3e 100644
--- a/Demos/LunarG-VulkanSamples/Hologram/Hologram.xcodeproj/project.pbxproj
+++ b/Demos/LunarG-VulkanSamples/Hologram/Hologram.xcodeproj/project.pbxproj
@@ -266,11 +266,6 @@
 			isa = PBXProject;
 			attributes = {
 				LastUpgradeCheck = 1110;
-				TargetAttributes = {
-					A977BCBD1B66BB010067E5BF = {
-						DevelopmentTeam = VU3TCKU48B;
-					};
-				};
 			};
 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Hologram" */;
 			compatibilityVersion = "Xcode 8.0";
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index db86868..b7dd816 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -26,6 +26,9 @@
 - Use native texture swizzling when available.
 - Set default value of the `MVK_ALLOW_METAL_FENCES` environment variable to `1 (true)`, 
   to enable use of `MTLFence` for Vulkan semaphores, by default.
+- Support additional capabilities in 1D images, including rendering, clearing,
+  and mipmaps. Add `MVK_CONFIG_TEXTURE_1D_AS_2D` environment variable to 
+  enable/disable these capabilities.
 - Use placement `MTLHeaps` for `VkDeviceMemory` when possible.
 - Report heap sizes accurately when possible.
 - Add support for additional colorspace options.
diff --git a/ExternalDependencies.xcodeproj/project.pbxproj b/ExternalDependencies.xcodeproj/project.pbxproj
index 38d8409..e3b2b57 100644
--- a/ExternalDependencies.xcodeproj/project.pbxproj
+++ b/ExternalDependencies.xcodeproj/project.pbxproj
@@ -1108,6 +1108,7 @@
 		450A4F64221C5A95007203D7 /* spirv_reflect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_reflect.cpp; sourceTree = "<group>"; };
 		A90FD89F21CC4EAB00B92BB2 /* libSPIRVCross.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSPIRVCross.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		A90FD9E421CC4EB900B92BB2 /* libSPIRVCross.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSPIRVCross.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		A91BF011235F9C510039B7DE /* gen_spirv_cross_rev_hdr.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = gen_spirv_cross_rev_hdr.sh; sourceTree = "<group>"; };
 		A9679AAC21D269D900856BF7 /* package_ext_libs_macos.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_ext_libs_macos.sh; sourceTree = "<group>"; };
 		A9679AAD21D269D900856BF7 /* package_ext_libs_ios.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_ext_libs_ios.sh; sourceTree = "<group>"; };
 		A9679AAE21D269D900856BF7 /* package_ext_libs.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_ext_libs.sh; sourceTree = "<group>"; };
@@ -1642,6 +1643,7 @@
 		A9679AAB21D2699800856BF7 /* Scripts */ = {
 			isa = PBXGroup;
 			children = (
+				A91BF011235F9C510039B7DE /* gen_spirv_cross_rev_hdr.sh */,
 				A9679AAD21D269D900856BF7 /* package_ext_libs_ios.sh */,
 				A9679AAC21D269D900856BF7 /* package_ext_libs_macos.sh */,
 				A9679AAE21D269D900856BF7 /* package_ext_libs.sh */,
@@ -2880,6 +2882,7 @@
 			buildPhases = (
 				A976290021CC608E00B52A68 /* Headers */,
 				A976290121CC609100B52A68 /* Sources */,
+				A91BF013235F9EED0039B7DE /* Generate Revision Header */,
 			);
 			buildRules = (
 			);
@@ -2896,6 +2899,7 @@
 			buildPhases = (
 				A97628FF21CC608900B52A68 /* Headers */,
 				A97628FE21CC608400B52A68 /* Sources */,
+				A91BF012235F9E220039B7DE /* Generate Revision Header */,
 			);
 			buildRules = (
 			);
@@ -2976,7 +2980,7 @@
 		A9F55D25198BE6A7004EC31B /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 1100;
+				LastUpgradeCheck = 1110;
 				ORGANIZATIONNAME = "The Brenwill Workshop Ltd.";
 				TargetAttributes = {
 					A972A7E421CEC72F0013AB25 = {
@@ -3018,6 +3022,42 @@
 /* End PBXProject section */
 
 /* Begin PBXShellScriptBuildPhase section */
+		A91BF012235F9E220039B7DE /* Generate Revision Header */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+			);
+			name = "Generate Revision Header";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Scripts/gen_spirv_cross_rev_hdr.sh\"\n";
+		};
+		A91BF013235F9EED0039B7DE /* Generate Revision Header */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+			);
+			name = "Generate Revision Header";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Scripts/gen_spirv_cross_rev_hdr.sh\"\n";
+		};
 		A9679AAF21D26C1400856BF7 /* Package External Libraries */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
diff --git "a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies \050Debug\051.xcscheme" "b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies \050Debug\051.xcscheme"
index 3d422f5..e283c6e 100644
--- "a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies \050Debug\051.xcscheme"
+++ "b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies \050Debug\051.xcscheme"
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-iOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-iOS.xcscheme
index 7a454af..0d81672 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-iOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-iOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-macOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-macOS.xcscheme
index e74ca3a..048ce30 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-macOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies-macOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies.xcscheme
index 079b27f..2f85c51 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/ExternalDependencies.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-iOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-iOS.xcscheme
index 7a3d597..d591127 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-iOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-iOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-macOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-macOS.xcscheme
index 251a517..3efa99c 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-macOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Cross-macOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-iOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-iOS.xcscheme
index 3851e6e..b9c5097 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-iOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-iOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-macOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-macOS.xcscheme
index 05f1f63..e6ca1b2 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-macOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/SPIRV-Tools-macOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-iOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-iOS.xcscheme
index 41cbb39..a1a56a3 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-iOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-iOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-macOS.xcscheme b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-macOS.xcscheme
index 3bf3607..a69c6b3 100644
--- a/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-macOS.xcscheme
+++ b/ExternalDependencies.xcodeproj/xcshareddata/xcschemes/glslang-macOS.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1100"
+   LastUpgradeVersion = "1110"
    version = "2.0">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/ExternalRevisions/SPIRV-Cross_repo_revision b/ExternalRevisions/SPIRV-Cross_repo_revision
index 999ffa7..7ab941b 100644
--- a/ExternalRevisions/SPIRV-Cross_repo_revision
+++ b/ExternalRevisions/SPIRV-Cross_repo_revision
@@ -1 +1 @@
-2082e7e80189843a52d9a79bc17787af93b517de
+b10f5d48c959c5600c5e103a6b955b6b1b59cdff
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index 7a8d8cf..4af8c07 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -100,7 +100,7 @@
  *      0: No logging.
  *      1: Log errors only.
  *      2: Log errors and informational messages.
- *    If neither is set, errors and informational messages are logged.
+ *    If none of these is set, errors and informational messages are logged.
  *
  * 2. The MVK_CONFIG_TRACE_VULKAN_CALLS runtime environment variable or MoltenVK compile-time build
  *    setting causes MoltenVK to log the name of each Vulkan call made by the application. The logging
@@ -114,6 +114,7 @@
  *
  * 3. Setting the MVK_CONFIG_FORCE_LOW_POWER_GPU runtime environment variable or MoltenVK compile-time
  *    build setting to 1 will force MoltenVK to use a low-power GPU, if one is availble on the device.
+ *    By default, this setting is disabled, allowing both low-power and high-power GPU's to be used.
  *
  * 4. Setting the MVK_ALLOW_METAL_FENCES or MVK_ALLOW_METAL_EVENTS runtime environment variable
  *    or MoltenVK compile-time build setting to 1 will cause MoltenVK to use MTLFence or MTLEvent,
@@ -136,6 +137,13 @@
  *      0: No automatic GPU capture.
  *      1: Capture all GPU commands issued during the lifetime of the VkDevice.
  *    If none of these is set, no automatic GPU capture will occur.
+ *
+ * 6. The MVK_CONFIG_TEXTURE_1D_AS_2D runtime environment variable or MoltenVK compile-time build
+ *    setting controls whether MoltenVK should use a Metal 2D texture with a height of 1 for a
+ *    Vulkan 1D image, or use a native Metal 1D texture. Metal imposes significant restrictions
+ *    on native 1D textures, including not being renderable, clearable, or permitting mipmaps.
+ *    Using a Metal 2D texture allows Vulkan 1D textures to support this additional functionality.
+ *    This setting is enabled by default, and MoltenVK will use a Metal 2D texture for each Vulkan 1D image.
  */
 typedef struct {
 
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
index 71b5fb6..435fd79 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
@@ -1061,7 +1061,7 @@
 
 	// Validate
 	if (_image->getImageType() == VK_IMAGE_TYPE_1D) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClearImage(): 1D images cannot be cleared on this device."));
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClearImage(): Native 1D images cannot be cleared on this device. Consider enabling MVK_CONFIG_TEXTURE_1D_AS_2D."));
 	}
 	if ((_isDepthStencilClear && !_image->getSupportsAllFormatFeatures(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) ||
 		(!_isDepthStencilClear && !_image->getSupportsAllFormatFeatures(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))) {
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm
index b2d18e3..15ba867 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm
@@ -175,7 +175,7 @@
 #pragma mark Metal
 
 id<MTLTexture> MVKBufferView::getMTLTexture() {
-    if ( !_mtlTexture && _mtlPixelFormat &&  _device->_pMetalFeatures->texelBuffers) {
+    if ( !_mtlTexture && _mtlPixelFormat && _device->_pMetalFeatures->texelBuffers) {
 
 		// Lock and check again in case another thread has created the texture.
 		lock_guard<mutex> lock(_lock);
@@ -201,9 +201,9 @@
             mtlTexDesc.cpuCacheMode = mtlBuff.cpuCacheMode;
             mtlTexDesc.usage = usage;
         }
-		_mtlTexture = [_buffer->getMTLBuffer() newTextureWithDescriptor: mtlTexDesc
-																 offset: _mtlBufferOffset
-															bytesPerRow: _mtlBytesPerRow];
+		_mtlTexture = [mtlBuff newTextureWithDescriptor: mtlTexDesc
+												 offset: _mtlBufferOffset
+											bytesPerRow: _mtlBytesPerRow];
 		propogateDebugName();
     }
     return _mtlTexture;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index b116ae6..d68ceb1 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -264,21 +264,26 @@
 	VkSampleCountFlags sampleCounts = _metalFeatures.supportedSampleCounts;
     switch (type) {
         case VK_IMAGE_TYPE_1D:
-			// Metal does not allow 1D textures to be used as attachments
-			if (hasAttachmentUsage) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
+			maxExt.height = 1;
+			maxExt.depth = 1;
+			if (_mvkTexture1DAs2D) {
+				maxExt.width = pLimits->maxImageDimension2D;
+				maxLevels = mvkMipmapLevels3D(maxExt);
+			} else {
+				maxExt.width = pLimits->maxImageDimension1D;
+				maxLevels = 1;
+				sampleCounts = VK_SAMPLE_COUNT_1_BIT;
 
-			// Metal does not allow linear tiling on 1D textures
-			if (tiling == VK_IMAGE_TILING_LINEAR) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
+				// Metal does not allow native 1D textures to be used as attachments
+				if (hasAttachmentUsage ) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
 
-			// Metal does not allow compressed or depth/stencil formats on 1D textures
-			if (mvkFmt == kMVKFormatDepthStencil || mvkFmt == kMVKFormatCompressed) {
-				return VK_ERROR_FORMAT_NOT_SUPPORTED;
+				// Metal does not allow linear tiling on native 1D textures
+				if (tiling == VK_IMAGE_TILING_LINEAR) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
+
+				// Metal does not allow compressed or depth/stencil formats on native 1D textures
+				if (mvkFmt == kMVKFormatDepthStencil) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
+				if (mvkFmt == kMVKFormatCompressed) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
 			}
-            maxExt.width = pLimits->maxImageDimension1D;
-            maxExt.height = 1;
-            maxExt.depth = 1;
-			maxLevels = 1;
-            sampleCounts = VK_SAMPLE_COUNT_1_BIT;
             break;
         case VK_IMAGE_TYPE_2D:
             if (mvkIsAnyFlagEnabled(flags, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ) {
@@ -1197,11 +1202,9 @@
 	_properties.limits.maxDescriptorSetStorageImages = (_properties.limits.maxPerStageDescriptorStorageImages * 4);
 	_properties.limits.maxDescriptorSetInputAttachments = (_properties.limits.maxPerStageDescriptorInputAttachments * 4);
 
-	if (_metalFeatures.textureBuffers) {
-		_properties.limits.maxTexelBufferElements = (uint32_t)_metalFeatures.maxMTLBufferSize;
-	} else {
-		_properties.limits.maxTexelBufferElements = _properties.limits.maxImageDimension2D * _properties.limits.maxImageDimension2D;
-	}
+	// Whether handled as a real texture buffer or a 2D texture, this value is likely nowhere near the size of a buffer,
+	// needs to fit in 32 bits, and some apps (I'm looking at you, CTS), assume it is low when doing 32-bit math.
+	_properties.limits.maxTexelBufferElements = _properties.limits.maxImageDimension2D * (4 * KIBI);
 #if MVK_MACOS
 	_properties.limits.maxUniformBufferRange = (64 * KIBI);
 #endif
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index 2e25267..4b37b30 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -56,7 +56,11 @@
 	/** Returns the debug report object type of this object. */
 	VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT; }
 
-	/** Returns the Vulkan image type of this image. */
+	/**
+	 * Returns the Vulkan image type of this image.
+	 * This may be different than the value originally specified for the image
+	 * if a 1D texture is being handled via a Metal 2D texture with height of 1.
+	 */
     VkImageType getImageType();
 
     /** Returns the Vulkan image format of this image. */
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index df00a3b..8d0633a 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -617,16 +617,18 @@
 																 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
 																 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
 																 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT));
-	validateConfig(pCreateInfo, isAttachment);
+	// Texture type depends on validated samples. Other validation depends on possibly modified texture type.
 	_samples = validateSamples(pCreateInfo, isAttachment);
+	_mtlTextureType = mvkMTLTextureTypeFromVkImageType(pCreateInfo->imageType, _arrayLayers, _samples > VK_SAMPLE_COUNT_1_BIT);
+
+	validateConfig(pCreateInfo, isAttachment);
 	_mipLevels = validateMipLevels(pCreateInfo, isAttachment);
 	_isLinear = validateLinear(pCreateInfo, isAttachment);
 
 	_mtlPixelFormat = getMTLPixelFormatFromVkFormat(pCreateInfo->format);
-	_mtlTextureType = mvkMTLTextureTypeFromVkImageType(pCreateInfo->imageType, _arrayLayers, _samples > VK_SAMPLE_COUNT_1_BIT);
 	_usage = pCreateInfo->usage;
 
-	_is3DCompressed = (pCreateInfo->imageType == VK_IMAGE_TYPE_3D) && (mvkFormatTypeFromVkFormat(pCreateInfo->format) == kMVKFormatCompressed) && !getDevice()->_pMetalFeatures->native3DCompressedTextures;
+	_is3DCompressed = (getImageType() == VK_IMAGE_TYPE_3D) && (mvkFormatTypeFromVkFormat(pCreateInfo->format) == kMVKFormatCompressed) && !getDevice()->_pMetalFeatures->native3DCompressedTextures;
 	_isDepthStencilAttachment = (mvkAreAllFlagsEnabled(pCreateInfo->usage, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ||
 								 mvkAreAllFlagsEnabled(mvkVkFormatProperties(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT));
 	_canSupportMTLTextureView = !_isDepthStencilAttachment || _device->_pMetalFeatures->stencilViews;
@@ -650,50 +652,14 @@
     initSubresources(pCreateInfo);
 }
 
-void MVKImage::validateConfig(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
-
-	bool is2D = pCreateInfo->imageType == VK_IMAGE_TYPE_2D;
-	bool isCompressed = mvkFormatTypeFromVkFormat(pCreateInfo->format) == kMVKFormatCompressed;
-
-#if MVK_IOS
-	if (isCompressed && !is2D) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, compressed formats may only be used with 2D images."));
-	}
-#endif
-#if MVK_MACOS
-	if (isCompressed && !is2D) {
-		if (pCreateInfo->imageType != VK_IMAGE_TYPE_3D) {
-			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, compressed formats may only be used with 2D or 3D images."));
-		} else if (!getDevice()->_pMetalFeatures->native3DCompressedTextures && !mvkCanDecodeFormat(pCreateInfo->format)) {
-			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, the %s compressed format may only be used with 2D images.", mvkVkFormatName(pCreateInfo->format)));
-		}
-	}
-#endif
-
-	if ((mvkFormatTypeFromVkFormat(pCreateInfo->format) == kMVKFormatDepthStencil) && !is2D ) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, depth/stencil formats may only be used with 2D images."));
-	}
-	if (isAttachment && (pCreateInfo->arrayLayers > 1) && !_device->_pMetalFeatures->layeredRendering) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to array (layered) attachments."));
-	}
-	if (isAttachment && (pCreateInfo->imageType == VK_IMAGE_TYPE_1D)) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to 1D attachments."));
-	}
-	if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not allow uncompressed views of compressed images."));
-	}
-	if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT)) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not support split-instance memory binding."));
-	}
-}
-
 VkSampleCountFlagBits MVKImage::validateSamples(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
 
 	VkSampleCountFlagBits validSamples = pCreateInfo->samples;
 
 	if (validSamples == VK_SAMPLE_COUNT_1_BIT) { return validSamples; }
 
-	if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D) {
+	// Don't use getImageType() because it hasn't been set yet.
+	if ( !((pCreateInfo->imageType == VK_IMAGE_TYPE_2D) || ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) && _mvkTexture1DAs2D)) ) {
 		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, multisampling can only be used with a 2D image type. Setting sample count to 1."));
 		validSamples = VK_SAMPLE_COUNT_1_BIT;
 	}
@@ -717,14 +683,51 @@
 	return validSamples;
 }
 
+void MVKImage::validateConfig(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
+
+	bool is2D = (getImageType() == VK_IMAGE_TYPE_2D);
+	bool isCompressed = mvkFormatTypeFromVkFormat(pCreateInfo->format) == kMVKFormatCompressed;
+
+#if MVK_IOS
+	if (isCompressed && !is2D) {
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, compressed formats may only be used with 2D images."));
+	}
+#endif
+#if MVK_MACOS
+	if (isCompressed && !is2D) {
+		if (getImageType() != VK_IMAGE_TYPE_3D) {
+			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, compressed formats may only be used with 2D or 3D images."));
+		} else if (!getDevice()->_pMetalFeatures->native3DCompressedTextures && !mvkCanDecodeFormat(pCreateInfo->format)) {
+			setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, the %s compressed format may only be used with 2D images.", mvkVkFormatName(pCreateInfo->format)));
+		}
+	}
+#endif
+
+	if ((mvkFormatTypeFromVkFormat(pCreateInfo->format) == kMVKFormatDepthStencil) && !is2D ) {
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, depth/stencil formats may only be used with 2D images."));
+	}
+	if (isAttachment && (pCreateInfo->arrayLayers > 1) && !_device->_pMetalFeatures->layeredRendering) {
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : This device does not support rendering to array (layered) attachments."));
+	}
+	if (isAttachment && (getImageType() == VK_IMAGE_TYPE_1D)) {
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not support rendering to native 1D attachments. Consider enabling MVK_CONFIG_TEXTURE_1D_AS_2D."));
+	}
+	if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) {
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not allow uncompressed views of compressed images."));
+	}
+	if (mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT)) {
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Metal does not support split-instance memory binding."));
+	}
+}
+
 uint32_t MVKImage::validateMipLevels(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
 	uint32_t minDim = 1;
 	uint32_t validMipLevels = max(pCreateInfo->mipLevels, minDim);
 
 	if (validMipLevels == 1) { return validMipLevels; }
 
-	if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D) {
-		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, 1D images cannot use mipmaps. Setting mip levels to 1."));
+	if (getImageType() == VK_IMAGE_TYPE_1D) {
+		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, native 1D images cannot use mipmaps. Setting mip levels to 1. Consider enabling MVK_CONFIG_TEXTURE_1D_AS_2D."));
 		validMipLevels = 1;
 	}
 
@@ -737,7 +740,7 @@
 
 	bool isLin = true;
 
-	if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D) {
+	if (getImageType() != VK_IMAGE_TYPE_2D) {
 		setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, imageType must be VK_IMAGE_TYPE_2D."));
 		isLin = false;
 	}
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index cd0a2dc..48a3f6e 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -1157,6 +1157,7 @@
     _tessCtlPatchOutputBufferIndex = layout->getTessCtlPatchOutputBufferIndex();
     _tessCtlLevelBufferIndex = layout->getTessCtlLevelBufferIndex();
 
+	shaderContext.options.mslOptions.texture_1D_as_2D = _mvkTexture1DAs2D;
     shaderContext.options.mslOptions.enable_point_size_builtin = isRenderingPoints(pCreateInfo, reflectData);
     shaderContext.options.shouldFlipVertexY = _device->_pMVKConfig->shaderConversionFlipVertexY;
     shaderContext.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle;
@@ -1349,6 +1350,7 @@
 	shaderContext.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle;
 	shaderContext.options.mslOptions.texture_buffer_native = _device->_pMetalFeatures->textureBuffers;
 	shaderContext.options.mslOptions.dispatch_base = _allowsDispatchBase;
+	shaderContext.options.mslOptions.texture_1D_as_2D = _mvkTexture1DAs2D;
 
     MVKPipelineLayout* layout = (MVKPipelineLayout*)pCreateInfo->layout;
     layout->populateShaderConverterContext(shaderContext);
@@ -1615,12 +1617,19 @@
 				opt.shader_patch_output_buffer_index,
 				opt.shader_tess_factor_buffer_index,
 				opt.buffer_size_buffer_index,
+				opt.view_mask_buffer_index,
+				opt.dynamic_offsets_buffer_index,
 				opt.shader_input_wg_index,
+				opt.device_index,
 				opt.enable_point_size_builtin,
 				opt.disable_rasterization,
 				opt.capture_output_to_buffer,
 				opt.swizzle_texture_samples,
 				opt.tess_domain_origin_lower_left,
+				opt.multiview,
+				opt.view_index_from_device_index,
+				opt.dispatch_base,
+				opt.texture_1D_as_2D,
 				opt.argument_buffers,
 				opt.pad_fragment_output_components,
 				opt.texture_buffer_native);
diff --git a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
index ae1c4bd..2f40b2f 100644
--- a/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
+++ b/MoltenVK/MoltenVK/Utility/MVKEnvironment.h
@@ -184,6 +184,11 @@
 #   define MVK_ALLOW_METAL_EVENTS    0
 #endif
 
+/** Substitute Metal 2D textures for Vulkan 1D images. Enabled by default. */
+#ifndef MVK_CONFIG_TEXTURE_1D_AS_2D
+#   define MVK_CONFIG_TEXTURE_1D_AS_2D    1
+#endif
+
 /**
  * IOSurfaces are supported on macOS, and on iOS starting with iOS 11.
  *
diff --git a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.hpp b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.hpp
index 617db53..66c880d 100644
--- a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.hpp
+++ b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.hpp
@@ -31,6 +31,9 @@
  * which is part of the public external MoltenVK C API.
  */
 
+/** Support the MVK_CONFIG_TEXTURE_1D_AS_2D runtime environment variable. */
+extern bool _mvkTexture1DAs2D;
+
 
 #pragma mark -
 #pragma mark Support for VK_EXT_debug_report extension
diff --git a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
index a24700f..c0a631f 100644
--- a/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
+++ b/MoltenVK/MoltenVK/Vulkan/mvk_datatypes.mm
@@ -821,8 +821,10 @@
 																  uint32_t arraySize,
 																  bool isMultisample) {
 	switch (vkImageType) {
-		case VK_IMAGE_TYPE_1D: return (arraySize > 1 ? MTLTextureType1DArray : MTLTextureType1D);
 		case VK_IMAGE_TYPE_3D: return MTLTextureType3D;
+		case VK_IMAGE_TYPE_1D: return (_mvkTexture1DAs2D
+									   ? mvkMTLTextureTypeFromVkImageType(VK_IMAGE_TYPE_2D, arraySize, isMultisample)
+									   : (arraySize > 1 ? MTLTextureType1DArray : MTLTextureType1D));
 		case VK_IMAGE_TYPE_2D:
 		default: {
 #if MVK_MACOS
@@ -846,22 +848,24 @@
 			return VK_IMAGE_TYPE_2D;
 	}
 }
-
 MVK_PUBLIC_SYMBOL MTLTextureType mvkMTLTextureTypeFromVkImageViewType(VkImageViewType vkImageViewType,
 																	  bool isMultisample) {
 	switch (vkImageViewType) {
-		case VK_IMAGE_VIEW_TYPE_1D:				return MTLTextureType1D;
-		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:		return MTLTextureType1DArray;
-		case VK_IMAGE_VIEW_TYPE_2D:				return (isMultisample ? MTLTextureType2DMultisample : MTLTextureType2D);
+		case VK_IMAGE_VIEW_TYPE_3D:			return MTLTextureType3D;
+		case VK_IMAGE_VIEW_TYPE_CUBE:		return MTLTextureTypeCube;
+		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:	return MTLTextureTypeCubeArray;
+		case VK_IMAGE_VIEW_TYPE_1D:			return _mvkTexture1DAs2D ? mvkMTLTextureTypeFromVkImageViewType(VK_IMAGE_VIEW_TYPE_2D, isMultisample) : MTLTextureType1D;
+		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:	return _mvkTexture1DAs2D ? mvkMTLTextureTypeFromVkImageViewType(VK_IMAGE_VIEW_TYPE_2D_ARRAY, isMultisample) : MTLTextureType1DArray;
+
 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
 #if MVK_MACOS
 			if (isMultisample) { return MTLTextureType2DMultisampleArray; }
 #endif
 			return MTLTextureType2DArray;
-		case VK_IMAGE_VIEW_TYPE_3D:				return MTLTextureType3D;
-		case VK_IMAGE_VIEW_TYPE_CUBE:			return MTLTextureTypeCube;
-		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:		return MTLTextureTypeCubeArray;
-		default:                            	return MTLTextureType2D;
+
+		case VK_IMAGE_VIEW_TYPE_2D:
+		default:
+			return (isMultisample ? MTLTextureType2DMultisample : MTLTextureType2D);
 	}
 }
 
@@ -1450,6 +1454,8 @@
 #pragma mark -
 #pragma mark Library initialization
 
+bool _mvkTexture1DAs2D = MVK_CONFIG_TEXTURE_1D_AS_2D;
+
 /**
  * Called automatically when the framework is loaded and initialized.
  *
@@ -1461,6 +1467,8 @@
 
 	MVKInitFormatMaps();
 
+	MVK_SET_FROM_ENV_OR_BUILD_BOOL(_mvkTexture1DAs2D, MVK_CONFIG_TEXTURE_1D_AS_2D);
+
 	_mvkDataTypesInitialized = true;
 }
 
diff --git a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
index 59790c3..126c93a 100644
--- a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
+++ b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
@@ -63,6 +63,7 @@
 	if (mslOptions.argument_buffers != other.mslOptions.argument_buffers) { return false; }
 	if (mslOptions.pad_fragment_output_components != other.mslOptions.pad_fragment_output_components) { return false; }
 	if (mslOptions.texture_buffer_native != other.mslOptions.texture_buffer_native) { return false; }
+	if (mslOptions.texture_1D_as_2D != other.mslOptions.texture_1D_as_2D) { return false; }
 
 	return true;
 }
diff --git a/Scripts/gen_spirv_cross_rev_hdr.sh b/Scripts/gen_spirv_cross_rev_hdr.sh
new file mode 100755
index 0000000..d4311a6
--- /dev/null
+++ b/Scripts/gen_spirv_cross_rev_hdr.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# Record the SPIRV-Cross revision as a derived header file suitable for including in a build
+EXT_DIR="${SRCROOT}/External"
+EXT_REV_DIR="${SRCROOT}/ExternalRevisions"
+REPO_NAME=SPIRV-Cross
+REPO_REV=$(cat "${EXT_REV_DIR}/${REPO_NAME}_repo_revision")
+HDR_FILE=${EXT_DIR}/${REPO_NAME}/mvkSpirvCrossRevisionDerived.h
+echo "// Auto-generated by MoltenVK" > ${HDR_FILE}
+echo "static const char* spirvCrossRevisionString = \"${REPO_REV}\";" >> ${HDR_FILE}
+
diff --git a/fetchDependencies b/fetchDependencies
index 89ad70e..08ce79e 100755
--- a/fetchDependencies
+++ b/fetchDependencies
@@ -197,10 +197,6 @@
 	update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
 fi
 
-# Record the SPIRV-Cross revision as a derived header file suitable for including in a build
-HDR_FILE=${REPO_NAME}/mvkSpirvCrossRevisionDerived.h
-echo "// Auto-generated by MoltenVK" > ${HDR_FILE}
-echo "static const char* spirvCrossRevisionString = \"${REPO_REV}\";" >> ${HDR_FILE}
 
 
 # ----------------- glslang -------------------