Skip to content

Commit

Permalink
Support the VK_EXT_fragment_shader_interlock extension.
Browse files Browse the repository at this point in the history
This extension allows fragment shaders to delineate critical sections
where pairs of invocations may not execute simultaneously. In Metal, the
nearest equivalent functionality is raster order groups. This
implementation is thus implemented on top of them.

Update SPIRV-Cross to pull in SPIR-V support for this new extension.
  • Loading branch information
cdavis5e committed Sep 6, 2019
1 parent 73ac6b6 commit deaaab8
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 3 deletions.
1 change: 1 addition & 0 deletions Docs/MoltenVK_Runtime_UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ In addition to the core *Vulkan* API, **MoltenVK** also supports the following
- `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`
Expand Down
21 changes: 21 additions & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Released TBD

- 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.
Expand All @@ -44,7 +45,27 @@ Released TBD
`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.



Expand Down
2 changes: 1 addition & 1 deletion ExternalRevisions/SPIRV-Cross_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4ce04480ec5469fe7ebbdd66c3016090a704d81b
2082e7e80189843a52d9a79bc17787af93b517de
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ typedef struct {
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;

/**
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject {
const VkPhysicalDeviceFloat16Int8FeaturesKHR _enabledF16I8Features;
const VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR _enabledUBOLayoutFeatures;
const VkPhysicalDeviceVariablePointerFeatures _enabledVarPtrFeatures;
const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT _enabledInterlockFeatures;
const VkPhysicalDeviceHostQueryResetFeaturesEXT _enabledHostQryResetFeatures;
const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT _enabledScalarLayoutFeatures;
const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT _enabledTexelBuffAlignFeatures;
Expand Down
30 changes: 29 additions & 1 deletion MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -1648,6 +1660,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;
}
Expand Down Expand Up @@ -2291,6 +2306,7 @@
_enabledF16I8Features(),
_enabledUBOLayoutFeatures(),
_enabledVarPtrFeatures(),
_enabledInterlockFeatures(),
_enabledHostQryResetFeatures(),
_enabledScalarLayoutFeatures(),
_enabledTexelBuffAlignFeatures(),
Expand Down Expand Up @@ -2405,6 +2421,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));
Expand Down Expand Up @@ -2432,9 +2449,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;
Expand Down Expand Up @@ -2510,6 +2531,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,
Expand Down
1 change: 1 addition & 0 deletions MoltenVK/MoltenVK/Layers/MVKExtensions.def
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ MVK_EXTENSION(KHR_variable_pointers, KHR_VARIABLE_POINTERS, MVK_EXTENSION_DEVICE
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)
Expand Down
6 changes: 6 additions & 0 deletions MoltenVK/MoltenVK/Layers/MVKExtensions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ static VkExtensionProperties mvkMakeExtProps(const char* extensionName, uint32_t
// 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;
}
Expand All @@ -66,6 +69,9 @@ static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
#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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ void SPIRVToMSLConverter::populateWorkgroupDimension(SPIRVWorkgroupSizeDimension
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;
}

Expand Down

0 comments on commit deaaab8

Please sign in to comment.