Support compiling MSL with position invariance if indicated in SPIRV shader.

Add SPIRVToMSLConversionResults::isPositionInvariant to query
position invariance from SPIR-V.
MVKDevice::getMTLCompileOptions() takes into consideration need to preserve invariance.
MVKShaderModule compile MSL to preserve invariance if required by shader.
This commit is contained in:
Bill Hollings 2021-01-28 16:46:49 -05:00
parent 2343c0267b
commit 3e20e1a137
8 changed files with 19 additions and 9 deletions

View File

@ -21,6 +21,7 @@ Released TBD
- Advertise support for `shaderInt64` feature.
- Support fast math on MSL compiler via `MVKConfiguration::fastMathEnabled` configuration
setting and `MVK_CONFIG_FAST_MATH_ENABLED` environment variable (enabled by default).
- Support compiling MSL with position invariance if indicated in SPIRV shader.
- `vkGetMoltenVKConfigurationMVK()` and `vkSetMoltenVKConfigurationMVK()` functions
can now be used with a `VkInstance` from another Vulkan layer, or with a `VK_NULL_HANDLE VkInstance`.
- `MVKConfiguration` extended to cover all MoltenVK environment variables.

View File

@ -650,10 +650,12 @@ public:
/**
* Returns an autoreleased options object to be used when compiling MSL shaders.
* The useFastMath parameteris and-combined with MVKConfiguration::fastMathEnabled
* The useFastMath parameter is and-combined with MVKConfiguration::fastMathEnabled
* to determine whether to enable fast math optimizations in the compiled shader.
* The preserveInvariance parameter indicates that the shader requires the position
* output invariance across invocations (typically for the position output).
*/
MTLCompileOptions* getMTLCompileOptions(bool useFastMath = true);
MTLCompileOptions* getMTLCompileOptions(bool useFastMath = true, bool preserveInvariance = false);
/** Returns the Metal vertex buffer index to use for the specified vertex attribute binding number. */
uint32_t getMetalBufferIndexForVertexAttributeBinding(uint32_t binding);

View File

@ -3639,10 +3639,13 @@ id<MTLSamplerState> MVKDevice::getDefaultMTLSamplerState() {
return _defaultMTLSamplerState;
}
MTLCompileOptions* MVKDevice::getMTLCompileOptions(bool useFastMath) {
MTLCompileOptions* MVKDevice::getMTLCompileOptions(bool useFastMath, bool preserveInvariance) {
MTLCompileOptions* mtlCompOpt = [MTLCompileOptions new];
mtlCompOpt.languageVersion = _pMetalFeatures->mslVersionEnum;
mtlCompOpt.fastMathEnabled = useFastMath && mvkGetMVKConfiguration()->fastMathEnabled;
if ([mtlCompOpt respondsToSelector: @selector(setPreserveInvariance:)]) {
[mtlCompOpt setPreserveInvariance: preserveInvariance];
}
return [mtlCompOpt autorelease];
}

View File

@ -2114,6 +2114,7 @@ namespace mvk {
void serialize(Archive & archive, SPIRVToMSLConversionResults& scr) {
archive(scr.entryPoint,
scr.isRasterizationDisabled,
scr.isPositionInvariant,
scr.needsSwizzleBuffer,
scr.needsOutputBuffer,
scr.needsPatchOutputBuffer,

View File

@ -254,7 +254,8 @@ public:
* If the Metal library compiler does not return within MVKConfiguration::metalCompileTimeout
* nanoseconds, an error will be generated and logged, and nil will be returned.
*/
id<MTLLibrary> newMTLLibrary(NSString* mslSourceCode, bool useFastMath);
id<MTLLibrary> newMTLLibrary(NSString* mslSourceCode,
const SPIRVToMSLConversionResults& shaderConversionResults);
#pragma mark Construction

View File

@ -136,7 +136,7 @@ MVKShaderLibrary::MVKShaderLibrary(MVKVulkanAPIDeviceObject* owner,
MVKShaderLibraryCompiler* slc = new MVKShaderLibraryCompiler(_owner);
NSString* nsSrc = [[NSString alloc] initWithUTF8String: mslSourceCode.c_str()]; // temp retained
_mtlLibrary = slc->newMTLLibrary(nsSrc, shaderConversionResults.entryPoint.supportsFastMath); // retained
_mtlLibrary = slc->newMTLLibrary(nsSrc, shaderConversionResults); // retained
[nsSrc release]; // release temp string
slc->destroy();
@ -415,12 +415,14 @@ MVKShaderModule::~MVKShaderModule() {
#pragma mark -
#pragma mark MVKShaderLibraryCompiler
id<MTLLibrary> MVKShaderLibraryCompiler::newMTLLibrary(NSString* mslSourceCode, bool useFastMath) {
id<MTLLibrary> MVKShaderLibraryCompiler::newMTLLibrary(NSString* mslSourceCode,
const SPIRVToMSLConversionResults& shaderConversionResults) {
unique_lock<mutex> lock(_completionLock);
compile(lock, ^{
[_owner->getMTLDevice() newLibraryWithSource: mslSourceCode
options: _owner->getDevice()->getMTLCompileOptions(useFastMath)
options: _owner->getDevice()->getMTLCompileOptions(shaderConversionResults.entryPoint.supportsFastMath,
shaderConversionResults.isPositionInvariant)
completionHandler: ^(id<MTLLibrary> mtlLib, NSError* error) {
bool isLate = compileComplete(mtlLib, error);
if (isLate) { destroy(); }

View File

@ -298,6 +298,7 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfigur
// and mark which vertex attributes and resource bindings are used by the shader
populateEntryPoint(pMSLCompiler, context.options);
_shaderConversionResults.isRasterizationDisabled = pMSLCompiler && pMSLCompiler->get_is_rasterization_disabled();
_shaderConversionResults.isPositionInvariant = pMSLCompiler && pMSLCompiler->is_position_invariant();
_shaderConversionResults.needsSwizzleBuffer = pMSLCompiler && pMSLCompiler->needs_swizzle_buffer();
_shaderConversionResults.needsOutputBuffer = pMSLCompiler && pMSLCompiler->needs_output_buffer();
_shaderConversionResults.needsPatchOutputBuffer = pMSLCompiler && pMSLCompiler->needs_patch_output_buffer();
@ -306,8 +307,6 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfigur
_shaderConversionResults.needsDispatchBaseBuffer = pMSLCompiler && pMSLCompiler->needs_dispatch_base_buffer();
_shaderConversionResults.needsViewRangeBuffer = pMSLCompiler && pMSLCompiler->needs_view_mask_buffer();
for (auto& ctxSI : context.shaderInputs) {
ctxSI.isUsedByShader = pMSLCompiler->is_msl_shader_input_used(ctxSI.shaderInput.location);
}

View File

@ -204,6 +204,7 @@ namespace mvk {
typedef struct SPIRVToMSLConversionResults {
SPIRVEntryPoint entryPoint;
bool isRasterizationDisabled = false;
bool isPositionInvariant = false;
bool needsSwizzleBuffer = false;
bool needsOutputBuffer = false;
bool needsPatchOutputBuffer = false;