Merge pull request #734 from cdavis5e/fragment-shader-interlock
Support the VK_EXT_fragment_shader_interlock extension.
diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md
index 8fc20af..9bd6595 100644
--- a/Docs/MoltenVK_Runtime_UserGuide.md
+++ b/Docs/MoltenVK_Runtime_UserGuide.md
@@ -254,6 +254,7 @@
- `VK_EXT_debug_marker`
- `VK_EXT_debug_report`
- `VK_EXT_debug_utils`
+- `VK_EXT_fragment_shader_interlock` *(requires Metal 2.0 and Raster Order Groups)*
- `VK_EXT_host_query_reset`
- `VK_EXT_memory_budget` *(requires Metal 2.0)*
- `VK_EXT_metal_surface`
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 6ad0843..ad000f4 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -20,6 +20,7 @@
- Add support for extensions:
- `VK_KHR_device_group`
+ - `VK_EXT_fragment_shader_interlock`
- Add support for `VkEvent`, using either native `MTLEvent` or emulation when `MTLEvent` not available.
- `vkInvalidateMappedMemoryRanges()` synchronizes managed device memory to CPU.
- Track supported instance and device extensions correctly.
@@ -44,7 +45,27 @@
`MVKConfiguration::presentWithCommandBuffer` is now obsolete.
- Don't use `MTLCommandBuffer push/popDebugGroup` if not available.
- Add ability to automatically cause an *Xcode* GPU capture without developer intervention.
+- On macOS, limit uniform buffer bindings to 64k.
- Update `VK_MVK_MOLTENVK_SPEC_VERSION` to version 22.
+- Update to latest SPIRV-Cross version:
+ - MSL: Deal with array copies from and to threadgroup.
+ - MSL: Inline all emitted functions.
+ - MSL: Inline all non-entry-point functions.
+ - MSL: Add `{Base,}{Vertex,Instance}{,Index}` to `bitcast_from_builtin_load`.
+ - MSL: Add support for sampler Y'CbCr conversion.
+ - MSL: Force storage images on iOS to use discrete descriptors.
+ - MSL: Support dynamic offsets for buffers in argument buffers.
+ - Support the `SPV_EXT_fragment_shader_interlock` extension.
+ - Fix variable scope when switch block exits multiple times.
+ - Deal correctly with sign on bitfield operations.
+ - Elide branches to continue block when continue block is also a merge.
+ - Move branchless analysis to CFG.
+ - Deal with `ldexp` taking `uint` input.
+ - Do not allow base expressions for non-native row-major matrices.
+ - GLSL: Assume image and sampler can be `RelaxedPrecision`.
+ - GLSL: Fix post-depth coverage for ESSL.
+ - Fix `ParsedIR::mark_used_as_array_length(uint32_t id)`.
+ - Refactor into stronger types in public API.
diff --git a/ExternalRevisions/SPIRV-Cross_repo_revision b/ExternalRevisions/SPIRV-Cross_repo_revision
index fc4d9eb..999ffa7 100644
--- a/ExternalRevisions/SPIRV-Cross_repo_revision
+++ b/ExternalRevisions/SPIRV-Cross_repo_revision
@@ -1 +1 @@
-4ce04480ec5469fe7ebbdd66c3016090a704d81b
+2082e7e80189843a52d9a79bc17787af93b517de
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index fbd7978..3b5af92 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -547,6 +547,7 @@
VkBool32 textureBuffers; /**< If true, textures of type MTLTextureTypeBuffer are supported. */
VkBool32 postDepthCoverage; /**< If true, coverage masks in fragment shaders post-depth-test are supported. */
VkBool32 fences; /**< If true, Metal synchronization fences (MTLFence) are supported. */
+ VkBool32 rasterOrderGroups; /**< If true, Raster order groups in fragment shaders are supported. */
} MVKPhysicalDeviceMetalFeatures;
/**
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index 6649ba0..adbc3b2 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -638,6 +638,7 @@
const VkPhysicalDeviceFloat16Int8FeaturesKHR _enabledF16I8Features;
const VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR _enabledUBOLayoutFeatures;
const VkPhysicalDeviceVariablePointerFeatures _enabledVarPtrFeatures;
+ const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT _enabledInterlockFeatures;
const VkPhysicalDeviceHostQueryResetFeaturesEXT _enabledHostQryResetFeatures;
const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT _enabledScalarLayoutFeatures;
const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT _enabledTexelBuffAlignFeatures;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index bc89164..2456bfa 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -102,6 +102,13 @@
varPtrFeatures->variablePointers = true;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
+ auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
+ interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
+ interlockFeatures->fragmentShaderPixelInterlock = _metalFeatures.rasterOrderGroups;
+ interlockFeatures->fragmentShaderShadingRateInterlock = false; // Requires variable rate shading; not supported yet in Metal
+ break;
+ }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
auto* hostQueryResetFeatures = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)next;
hostQueryResetFeatures->hostQueryReset = true;
@@ -861,6 +868,11 @@
#endif
+ // Note the selector name, which is different from the property name.
+ if ( [_mtlDevice respondsToSelector: @selector(areRasterOrderGroupsSupported)] ) {
+ _metalFeatures.rasterOrderGroups = _mtlDevice.rasterOrderGroupsSupported;
+ }
+
if ( [_mtlDevice respondsToSelector: @selector(maxBufferLength)] ) {
_metalFeatures.maxMTLBufferSize = _mtlDevice.maxBufferLength;
}
@@ -1652,6 +1664,9 @@
MVKExtensionList* pWritableExtns = (MVKExtensionList*)&_supportedExtensions;
pWritableExtns->disableAllButEnabledDeviceExtensions();
+ if (!_metalFeatures.rasterOrderGroups) {
+ pWritableExtns->vk_EXT_fragment_shader_interlock.enabled = false;
+ }
if (!_metalFeatures.postDepthCoverage) {
pWritableExtns->vk_EXT_post_depth_coverage.enabled = false;
}
@@ -2295,6 +2310,7 @@
_enabledF16I8Features(),
_enabledUBOLayoutFeatures(),
_enabledVarPtrFeatures(),
+ _enabledInterlockFeatures(),
_enabledHostQryResetFeatures(),
_enabledScalarLayoutFeatures(),
_enabledTexelBuffAlignFeatures(),
@@ -2409,6 +2425,7 @@
memset((void*)&_enabledF16I8Features, 0, sizeof(_enabledF16I8Features));
memset((void*)&_enabledUBOLayoutFeatures, 0, sizeof(_enabledUBOLayoutFeatures));
memset((void*)&_enabledVarPtrFeatures, 0, sizeof(_enabledVarPtrFeatures));
+ memset((void*)&_enabledInterlockFeatures, 0, sizeof(_enabledInterlockFeatures));
memset((void*)&_enabledHostQryResetFeatures, 0, sizeof(_enabledHostQryResetFeatures));
memset((void*)&_enabledScalarLayoutFeatures, 0, sizeof(_enabledScalarLayoutFeatures));
memset((void*)&_enabledTexelBuffAlignFeatures, 0, sizeof(_enabledTexelBuffAlignFeatures));
@@ -2436,9 +2453,13 @@
pdHostQryResetFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
pdHostQryResetFeatures.pNext = &pdScalarLayoutFeatures;
+ VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT pdInterlockFeatures;
+ pdInterlockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT;
+ pdInterlockFeatures.pNext = &pdHostQryResetFeatures;
+
VkPhysicalDeviceVariablePointerFeatures pdVarPtrFeatures;
pdVarPtrFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
- pdVarPtrFeatures.pNext = &pdHostQryResetFeatures;
+ pdVarPtrFeatures.pNext = &pdInterlockFeatures;
VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR pdUBOLayoutFeatures;
pdUBOLayoutFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR;
@@ -2514,6 +2535,13 @@
&pdVarPtrFeatures.variablePointersStorageBuffer, 2);
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
+ auto* requestedFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
+ enableFeatures(&_enabledInterlockFeatures.fragmentShaderSampleInterlock,
+ &requestedFeatures->fragmentShaderSampleInterlock,
+ &pdInterlockFeatures.fragmentShaderSampleInterlock, 3);
+ break;
+ }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
auto* requestedFeatures = (VkPhysicalDeviceHostQueryResetFeaturesEXT*)next;
enableFeatures(&_enabledHostQryResetFeatures.hostQueryReset,
diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
index 8f8ab03..9a2a320 100644
--- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def
+++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def
@@ -67,6 +67,7 @@
MVK_EXTENSION(EXT_debug_marker, EXT_DEBUG_MARKER, MVK_EXTENSION_DEVICE)
MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT, MVK_EXTENSION_INSTANCE)
MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS, MVK_EXTENSION_INSTANCE)
+MVK_EXTENSION(EXT_fragment_shader_interlock, EXT_FRAGMENT_SHADER_INTERLOCK, MVK_EXTENSION_DEVICE)
MVK_EXTENSION(EXT_host_query_reset, EXT_HOST_QUERY_RESET, MVK_EXTENSION_DEVICE)
MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET, MVK_EXTENSION_DEVICE)
MVK_EXTENSION(EXT_metal_surface, EXT_METAL_SURFACE, MVK_EXTENSION_INSTANCE)
diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.mm b/MoltenVK/MoltenVK/Layers/MVKExtensions.mm
index 1a670ee..7d069b8 100644
--- a/MoltenVK/MoltenVK/Layers/MVKExtensions.mm
+++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.mm
@@ -47,6 +47,9 @@
// Returns whether the specified properties are valid for this platform
static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
#if MVK_MACOS
+ if (pProperties == &kVkExtProps_EXT_FRAGMENT_SHADER_INTERLOCK) {
+ return mvkOSVersion() >= 10.13;
+ }
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
return mvkOSVersion() >= 10.13;
}
@@ -66,6 +69,9 @@
#endif
#if MVK_IOS
if (pProperties == &kVkExtProps_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE) { return false; }
+ if (pProperties == &kVkExtProps_EXT_FRAGMENT_SHADER_INTERLOCK) {
+ return mvkOSVersion() >= 11.0;
+ }
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
return mvkOSVersion() >= 11.0;
}
diff --git a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
index e331486..59790c3 100644
--- a/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
+++ b/MoltenVKShaderConverter/MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.cpp
@@ -425,7 +425,7 @@
uint32_t size,
SPIRV_CROSS_NAMESPACE::SpecializationConstant& spvSpecConst) {
wgDim.size = max(size, 1u);
- wgDim.isSpecialized = (spvSpecConst.id != 0);
+ wgDim.isSpecialized = (uint32_t(spvSpecConst.id) != 0);
wgDim.specializationID = spvSpecConst.constant_id;
}