Merge pull request #764 from billhollings/master

Support additional capabilities in 1D images, including rendering, clearing, and mipmaps.
This commit is contained in:
Bill Hollings 2019-10-26 09:31:54 -04:00 committed by GitHub
commit 789ef74d11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 187 additions and 108 deletions

View File

@ -546,11 +546,6 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1110; LastUpgradeCheck = 1110;
TargetAttributes = {
A977BCBD1B66BB010067E5BF = {
DevelopmentTeam = VU3TCKU48B;
};
};
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "API-Samples" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "API-Samples" */;
compatibilityVersion = "Xcode 8.0"; compatibilityVersion = "Xcode 8.0";

View File

@ -235,11 +235,6 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1110; LastUpgradeCheck = 1110;
TargetAttributes = {
A9B53B0F1C3AC0BE00ABC6F6 = {
DevelopmentTeam = VU3TCKU48B;
};
};
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Cube" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Cube" */;
compatibilityVersion = "Xcode 8.0"; compatibilityVersion = "Xcode 8.0";

View File

@ -266,11 +266,6 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1110; LastUpgradeCheck = 1110;
TargetAttributes = {
A977BCBD1B66BB010067E5BF = {
DevelopmentTeam = VU3TCKU48B;
};
};
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Hologram" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Hologram" */;
compatibilityVersion = "Xcode 8.0"; compatibilityVersion = "Xcode 8.0";

View File

@ -26,6 +26,9 @@ Released 2019/10/28
- Use native texture swizzling when available. - Use native texture swizzling when available.
- Set default value of the `MVK_ALLOW_METAL_FENCES` environment variable to `1 (true)`, - Set default value of the `MVK_ALLOW_METAL_FENCES` environment variable to `1 (true)`,
to enable use of `MTLFence` for Vulkan semaphores, by default. 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. - Use placement `MTLHeaps` for `VkDeviceMemory` when possible.
- Report heap sizes accurately when possible. - Report heap sizes accurately when possible.
- Add support for additional colorspace options. - Add support for additional colorspace options.

View File

@ -1108,6 +1108,7 @@
450A4F64221C5A95007203D7 /* spirv_reflect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_reflect.cpp; sourceTree = "<group>"; }; 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; }; 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; }; 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>"; }; 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>"; }; 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>"; }; A9679AAE21D269D900856BF7 /* package_ext_libs.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = package_ext_libs.sh; sourceTree = "<group>"; };
@ -1642,6 +1643,7 @@
A9679AAB21D2699800856BF7 /* Scripts */ = { A9679AAB21D2699800856BF7 /* Scripts */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A91BF011235F9C510039B7DE /* gen_spirv_cross_rev_hdr.sh */,
A9679AAD21D269D900856BF7 /* package_ext_libs_ios.sh */, A9679AAD21D269D900856BF7 /* package_ext_libs_ios.sh */,
A9679AAC21D269D900856BF7 /* package_ext_libs_macos.sh */, A9679AAC21D269D900856BF7 /* package_ext_libs_macos.sh */,
A9679AAE21D269D900856BF7 /* package_ext_libs.sh */, A9679AAE21D269D900856BF7 /* package_ext_libs.sh */,
@ -2880,6 +2882,7 @@
buildPhases = ( buildPhases = (
A976290021CC608E00B52A68 /* Headers */, A976290021CC608E00B52A68 /* Headers */,
A976290121CC609100B52A68 /* Sources */, A976290121CC609100B52A68 /* Sources */,
A91BF013235F9EED0039B7DE /* Generate Revision Header */,
); );
buildRules = ( buildRules = (
); );
@ -2896,6 +2899,7 @@
buildPhases = ( buildPhases = (
A97628FF21CC608900B52A68 /* Headers */, A97628FF21CC608900B52A68 /* Headers */,
A97628FE21CC608400B52A68 /* Sources */, A97628FE21CC608400B52A68 /* Sources */,
A91BF012235F9E220039B7DE /* Generate Revision Header */,
); );
buildRules = ( buildRules = (
); );
@ -2976,7 +2980,7 @@
A9F55D25198BE6A7004EC31B /* Project object */ = { A9F55D25198BE6A7004EC31B /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1100; LastUpgradeCheck = 1110;
ORGANIZATIONNAME = "The Brenwill Workshop Ltd."; ORGANIZATIONNAME = "The Brenwill Workshop Ltd.";
TargetAttributes = { TargetAttributes = {
A972A7E421CEC72F0013AB25 = { A972A7E421CEC72F0013AB25 = {
@ -3018,6 +3022,42 @@
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXShellScriptBuildPhase 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 */ = { A9679AAF21D26C1400856BF7 /* Package External Libraries */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1100" LastUpgradeVersion = "1110"
version = "2.0"> version = "2.0">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1 +1 @@
2082e7e80189843a52d9a79bc17787af93b517de b10f5d48c959c5600c5e103a6b955b6b1b59cdff

View File

@ -100,7 +100,7 @@ typedef unsigned long MTLLanguageVersion;
* 0: No logging. * 0: No logging.
* 1: Log errors only. * 1: Log errors only.
* 2: Log errors and informational messages. * 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 * 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 * setting causes MoltenVK to log the name of each Vulkan call made by the application. The logging
@ -114,6 +114,7 @@ typedef unsigned long MTLLanguageVersion;
* *
* 3. Setting the MVK_CONFIG_FORCE_LOW_POWER_GPU runtime environment variable or MoltenVK compile-time * 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. * 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 * 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, * or MoltenVK compile-time build setting to 1 will cause MoltenVK to use MTLFence or MTLEvent,
@ -136,6 +137,13 @@ typedef unsigned long MTLLanguageVersion;
* 0: No automatic GPU capture. * 0: No automatic GPU capture.
* 1: Capture all GPU commands issued during the lifetime of the VkDevice. * 1: Capture all GPU commands issued during the lifetime of the VkDevice.
* If none of these is set, no automatic GPU capture will occur. * 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 { typedef struct {

View File

@ -1061,7 +1061,7 @@ void MVKCmdClearImage::setContent(VkImage image,
// Validate // Validate
if (_image->getImageType() == VK_IMAGE_TYPE_1D) { 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)) || if ((_isDepthStencilClear && !_image->getSupportsAllFormatFeatures(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) ||
(!_isDepthStencilClear && !_image->getSupportsAllFormatFeatures(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))) { (!_isDepthStencilClear && !_image->getSupportsAllFormatFeatures(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))) {

View File

@ -201,7 +201,7 @@ id<MTLTexture> MVKBufferView::getMTLTexture() {
mtlTexDesc.cpuCacheMode = mtlBuff.cpuCacheMode; mtlTexDesc.cpuCacheMode = mtlBuff.cpuCacheMode;
mtlTexDesc.usage = usage; mtlTexDesc.usage = usage;
} }
_mtlTexture = [_buffer->getMTLBuffer() newTextureWithDescriptor: mtlTexDesc _mtlTexture = [mtlBuff newTextureWithDescriptor: mtlTexDesc
offset: _mtlBufferOffset offset: _mtlBufferOffset
bytesPerRow: _mtlBytesPerRow]; bytesPerRow: _mtlBytesPerRow];
propogateDebugName(); propogateDebugName();

View File

@ -264,21 +264,26 @@ VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
VkSampleCountFlags sampleCounts = _metalFeatures.supportedSampleCounts; VkSampleCountFlags sampleCounts = _metalFeatures.supportedSampleCounts;
switch (type) { switch (type) {
case VK_IMAGE_TYPE_1D: case VK_IMAGE_TYPE_1D:
// Metal does not allow 1D textures to be used as attachments
if (hasAttachmentUsage) { return VK_ERROR_FORMAT_NOT_SUPPORTED; }
// 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 compressed or depth/stencil formats on 1D textures
if (mvkFmt == kMVKFormatDepthStencil || mvkFmt == kMVKFormatCompressed) {
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
maxExt.width = pLimits->maxImageDimension1D;
maxExt.height = 1; maxExt.height = 1;
maxExt.depth = 1; maxExt.depth = 1;
if (_mvkTexture1DAs2D) {
maxExt.width = pLimits->maxImageDimension2D;
maxLevels = mvkMipmapLevels3D(maxExt);
} else {
maxExt.width = pLimits->maxImageDimension1D;
maxLevels = 1; maxLevels = 1;
sampleCounts = VK_SAMPLE_COUNT_1_BIT; sampleCounts = VK_SAMPLE_COUNT_1_BIT;
// Metal does not allow native 1D textures to be used as attachments
if (hasAttachmentUsage ) { 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; }
}
break; break;
case VK_IMAGE_TYPE_2D: case VK_IMAGE_TYPE_2D:
if (mvkIsAnyFlagEnabled(flags, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ) { if (mvkIsAnyFlagEnabled(flags, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ) {
@ -1197,11 +1202,9 @@ void MVKPhysicalDevice::initProperties() {
_properties.limits.maxDescriptorSetStorageImages = (_properties.limits.maxPerStageDescriptorStorageImages * 4); _properties.limits.maxDescriptorSetStorageImages = (_properties.limits.maxPerStageDescriptorStorageImages * 4);
_properties.limits.maxDescriptorSetInputAttachments = (_properties.limits.maxPerStageDescriptorInputAttachments * 4); _properties.limits.maxDescriptorSetInputAttachments = (_properties.limits.maxPerStageDescriptorInputAttachments * 4);
if (_metalFeatures.textureBuffers) { // Whether handled as a real texture buffer or a 2D texture, this value is likely nowhere near the size of a buffer,
_properties.limits.maxTexelBufferElements = (uint32_t)_metalFeatures.maxMTLBufferSize; // needs to fit in 32 bits, and some apps (I'm looking at you, CTS), assume it is low when doing 32-bit math.
} else { _properties.limits.maxTexelBufferElements = _properties.limits.maxImageDimension2D * (4 * KIBI);
_properties.limits.maxTexelBufferElements = _properties.limits.maxImageDimension2D * _properties.limits.maxImageDimension2D;
}
#if MVK_MACOS #if MVK_MACOS
_properties.limits.maxUniformBufferRange = (64 * KIBI); _properties.limits.maxUniformBufferRange = (64 * KIBI);
#endif #endif

View File

@ -56,7 +56,11 @@ public:
/** Returns the debug report object type of this object. */ /** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT; } 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(); VkImageType getImageType();
/** Returns the Vulkan image format of this image. */ /** Returns the Vulkan image format of this image. */

View File

@ -617,16 +617,18 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
VK_IMAGE_USAGE_INPUT_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); _samples = validateSamples(pCreateInfo, isAttachment);
_mtlTextureType = mvkMTLTextureTypeFromVkImageType(pCreateInfo->imageType, _arrayLayers, _samples > VK_SAMPLE_COUNT_1_BIT);
validateConfig(pCreateInfo, isAttachment);
_mipLevels = validateMipLevels(pCreateInfo, isAttachment); _mipLevels = validateMipLevels(pCreateInfo, isAttachment);
_isLinear = validateLinear(pCreateInfo, isAttachment); _isLinear = validateLinear(pCreateInfo, isAttachment);
_mtlPixelFormat = getMTLPixelFormatFromVkFormat(pCreateInfo->format); _mtlPixelFormat = getMTLPixelFormatFromVkFormat(pCreateInfo->format);
_mtlTextureType = mvkMTLTextureTypeFromVkImageType(pCreateInfo->imageType, _arrayLayers, _samples > VK_SAMPLE_COUNT_1_BIT);
_usage = pCreateInfo->usage; _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) || _isDepthStencilAttachment = (mvkAreAllFlagsEnabled(pCreateInfo->usage, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ||
mvkAreAllFlagsEnabled(mvkVkFormatProperties(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)); mvkAreAllFlagsEnabled(mvkVkFormatProperties(pCreateInfo->format).optimalTilingFeatures, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT));
_canSupportMTLTextureView = !_isDepthStencilAttachment || _device->_pMetalFeatures->stencilViews; _canSupportMTLTextureView = !_isDepthStencilAttachment || _device->_pMetalFeatures->stencilViews;
@ -650,50 +652,14 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
initSubresources(pCreateInfo); 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 MVKImage::validateSamples(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
VkSampleCountFlagBits validSamples = pCreateInfo->samples; VkSampleCountFlagBits validSamples = pCreateInfo->samples;
if (validSamples == VK_SAMPLE_COUNT_1_BIT) { return validSamples; } 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.")); 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; validSamples = VK_SAMPLE_COUNT_1_BIT;
} }
@ -717,14 +683,51 @@ VkSampleCountFlagBits MVKImage::validateSamples(const VkImageCreateInfo* pCreate
return validSamples; 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 MVKImage::validateMipLevels(const VkImageCreateInfo* pCreateInfo, bool isAttachment) {
uint32_t minDim = 1; uint32_t minDim = 1;
uint32_t validMipLevels = max(pCreateInfo->mipLevels, minDim); uint32_t validMipLevels = max(pCreateInfo->mipLevels, minDim);
if (validMipLevels == 1) { return validMipLevels; } if (validMipLevels == 1) { return validMipLevels; }
if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D) { if (getImageType() == VK_IMAGE_TYPE_1D) {
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : Under Metal, 1D images cannot use mipmaps. Setting mip levels to 1.")); 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; validMipLevels = 1;
} }
@ -737,7 +740,7 @@ bool MVKImage::validateLinear(const VkImageCreateInfo* pCreateInfo, bool isAttac
bool isLin = true; 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.")); setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateImage() : If tiling is VK_IMAGE_TILING_LINEAR, imageType must be VK_IMAGE_TYPE_2D."));
isLin = false; isLin = false;
} }

View File

@ -1157,6 +1157,7 @@ void MVKGraphicsPipeline::initMVKShaderConverterContext(SPIRVToMSLConversionConf
_tessCtlPatchOutputBufferIndex = layout->getTessCtlPatchOutputBufferIndex(); _tessCtlPatchOutputBufferIndex = layout->getTessCtlPatchOutputBufferIndex();
_tessCtlLevelBufferIndex = layout->getTessCtlLevelBufferIndex(); _tessCtlLevelBufferIndex = layout->getTessCtlLevelBufferIndex();
shaderContext.options.mslOptions.texture_1D_as_2D = _mvkTexture1DAs2D;
shaderContext.options.mslOptions.enable_point_size_builtin = isRenderingPoints(pCreateInfo, reflectData); shaderContext.options.mslOptions.enable_point_size_builtin = isRenderingPoints(pCreateInfo, reflectData);
shaderContext.options.shouldFlipVertexY = _device->_pMVKConfig->shaderConversionFlipVertexY; shaderContext.options.shouldFlipVertexY = _device->_pMVKConfig->shaderConversionFlipVertexY;
shaderContext.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle; shaderContext.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle;
@ -1349,6 +1350,7 @@ MVKMTLFunction MVKComputePipeline::getMTLFunction(const VkComputePipelineCreateI
shaderContext.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle; shaderContext.options.mslOptions.swizzle_texture_samples = _fullImageViewSwizzle && !getDevice()->_pMetalFeatures->nativeTextureSwizzle;
shaderContext.options.mslOptions.texture_buffer_native = _device->_pMetalFeatures->textureBuffers; shaderContext.options.mslOptions.texture_buffer_native = _device->_pMetalFeatures->textureBuffers;
shaderContext.options.mslOptions.dispatch_base = _allowsDispatchBase; shaderContext.options.mslOptions.dispatch_base = _allowsDispatchBase;
shaderContext.options.mslOptions.texture_1D_as_2D = _mvkTexture1DAs2D;
MVKPipelineLayout* layout = (MVKPipelineLayout*)pCreateInfo->layout; MVKPipelineLayout* layout = (MVKPipelineLayout*)pCreateInfo->layout;
layout->populateShaderConverterContext(shaderContext); layout->populateShaderConverterContext(shaderContext);
@ -1615,12 +1617,19 @@ namespace SPIRV_CROSS_NAMESPACE {
opt.shader_patch_output_buffer_index, opt.shader_patch_output_buffer_index,
opt.shader_tess_factor_buffer_index, opt.shader_tess_factor_buffer_index,
opt.buffer_size_buffer_index, opt.buffer_size_buffer_index,
opt.view_mask_buffer_index,
opt.dynamic_offsets_buffer_index,
opt.shader_input_wg_index, opt.shader_input_wg_index,
opt.device_index,
opt.enable_point_size_builtin, opt.enable_point_size_builtin,
opt.disable_rasterization, opt.disable_rasterization,
opt.capture_output_to_buffer, opt.capture_output_to_buffer,
opt.swizzle_texture_samples, opt.swizzle_texture_samples,
opt.tess_domain_origin_lower_left, 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.argument_buffers,
opt.pad_fragment_output_components, opt.pad_fragment_output_components,
opt.texture_buffer_native); opt.texture_buffer_native);

View File

@ -184,6 +184,11 @@
# define MVK_ALLOW_METAL_EVENTS 0 # define MVK_ALLOW_METAL_EVENTS 0
#endif #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. * IOSurfaces are supported on macOS, and on iOS starting with iOS 11.
* *

View File

@ -31,6 +31,9 @@ class MVKBaseObject;
* which is part of the public external MoltenVK C API. * 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 -
#pragma mark Support for VK_EXT_debug_report extension #pragma mark Support for VK_EXT_debug_report extension

View File

@ -821,8 +821,10 @@ MVK_PUBLIC_SYMBOL MTLTextureType mvkMTLTextureTypeFromVkImageType(VkImageType vk
uint32_t arraySize, uint32_t arraySize,
bool isMultisample) { bool isMultisample) {
switch (vkImageType) { switch (vkImageType) {
case VK_IMAGE_TYPE_1D: return (arraySize > 1 ? MTLTextureType1DArray : MTLTextureType1D);
case VK_IMAGE_TYPE_3D: return MTLTextureType3D; 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: case VK_IMAGE_TYPE_2D:
default: { default: {
#if MVK_MACOS #if MVK_MACOS
@ -846,22 +848,24 @@ MVK_PUBLIC_SYMBOL VkImageType mvkVkImageTypeFromMTLTextureType(MTLTextureType mt
return VK_IMAGE_TYPE_2D; return VK_IMAGE_TYPE_2D;
} }
} }
MVK_PUBLIC_SYMBOL MTLTextureType mvkMTLTextureTypeFromVkImageViewType(VkImageViewType vkImageViewType, MVK_PUBLIC_SYMBOL MTLTextureType mvkMTLTextureTypeFromVkImageViewType(VkImageViewType vkImageViewType,
bool isMultisample) { bool isMultisample) {
switch (vkImageViewType) { switch (vkImageViewType) {
case VK_IMAGE_VIEW_TYPE_1D: return MTLTextureType1D; case VK_IMAGE_VIEW_TYPE_3D: return MTLTextureType3D;
case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return MTLTextureType1DArray; case VK_IMAGE_VIEW_TYPE_CUBE: return MTLTextureTypeCube;
case VK_IMAGE_VIEW_TYPE_2D: return (isMultisample ? MTLTextureType2DMultisample : MTLTextureType2D); 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: case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
#if MVK_MACOS #if MVK_MACOS
if (isMultisample) { return MTLTextureType2DMultisampleArray; } if (isMultisample) { return MTLTextureType2DMultisampleArray; }
#endif #endif
return MTLTextureType2DArray; return MTLTextureType2DArray;
case VK_IMAGE_VIEW_TYPE_3D: return MTLTextureType3D;
case VK_IMAGE_VIEW_TYPE_CUBE: return MTLTextureTypeCube; case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return MTLTextureTypeCubeArray; default:
default: return MTLTextureType2D; return (isMultisample ? MTLTextureType2DMultisample : MTLTextureType2D);
} }
} }
@ -1450,6 +1454,8 @@ MVK_PUBLIC_SYMBOL MTLResourceOptions mvkMTLResourceOptions(MTLStorageMode mtlSto
#pragma mark - #pragma mark -
#pragma mark Library initialization #pragma mark Library initialization
bool _mvkTexture1DAs2D = MVK_CONFIG_TEXTURE_1D_AS_2D;
/** /**
* Called automatically when the framework is loaded and initialized. * Called automatically when the framework is loaded and initialized.
* *
@ -1461,6 +1467,8 @@ __attribute__((constructor)) static void MVKInitDataTypes() {
MVKInitFormatMaps(); MVKInitFormatMaps();
MVK_SET_FROM_ENV_OR_BUILD_BOOL(_mvkTexture1DAs2D, MVK_CONFIG_TEXTURE_1D_AS_2D);
_mvkDataTypesInitialized = true; _mvkDataTypesInitialized = true;
} }

View File

@ -63,6 +63,7 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConversionOptions::matches(const SPIRVToMSLConv
if (mslOptions.argument_buffers != other.mslOptions.argument_buffers) { return false; } 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.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_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; return true;
} }

View File

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

View File

@ -197,10 +197,6 @@ else
update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV} update_repo ${REPO_NAME} ${REPO_URL} ${REPO_REV}
fi 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 ------------------- # ----------------- glslang -------------------