To improve cache hits when matching SPIRVToMSLConversionConfiguration structs
to each other to find cached shader, only consider current shader stage resources. Rename more references to ShaderConverterContext to ShaderConversionConfig.
This commit is contained in:
parent
64a69d0e51
commit
650e8f3a46
@ -22,6 +22,8 @@ Released TBD
|
|||||||
- Expose `vkGetIOSurfaceMVK()` and `vkUseIOSurfaceMVK()` without requiring _Objective-C_.
|
- Expose `vkGetIOSurfaceMVK()` and `vkUseIOSurfaceMVK()` without requiring _Objective-C_.
|
||||||
- Support _Xcode 12.5_ build settings, build warnings, and SDK change to availability of
|
- Support _Xcode 12.5_ build settings, build warnings, and SDK change to availability of
|
||||||
`[MTLDevice supportsBCTextureCompression]` on _Mac Catalyst_.
|
`[MTLDevice supportsBCTextureCompression]` on _Mac Catalyst_.
|
||||||
|
- Improve cache hits when matching `SPIRVToMSLConversionConfiguration` structs to each other
|
||||||
|
to find a cached shader, by only considering resources from the current shader stage.
|
||||||
- Rename `kMVKShaderStageMax` to `kMVKShaderStageCount`.
|
- Rename `kMVKShaderStageMax` to `kMVKShaderStageCount`.
|
||||||
- Fix internal reference from `SPIRV_CROSS_NAMESPACE_OVERRIDE` to `SPIRV_CROSS_NAMESPACE`.
|
- Fix internal reference from `SPIRV_CROSS_NAMESPACE_OVERRIDE` to `SPIRV_CROSS_NAMESPACE`.
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ protected:
|
|||||||
void propagateDebugName() override {}
|
void propagateDebugName() override {}
|
||||||
template<typename CreateInfo> void addMTLArgumentEncoders(MVKMTLFunction& mvkMTLFunc,
|
template<typename CreateInfo> void addMTLArgumentEncoders(MVKMTLFunction& mvkMTLFunc,
|
||||||
const CreateInfo* pCreateInfo,
|
const CreateInfo* pCreateInfo,
|
||||||
SPIRVToMSLConversionConfiguration& context,
|
SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||||
MVKShaderStage stage);
|
MVKShaderStage stage);
|
||||||
|
|
||||||
MVKPipelineCache* _pipelineCache;
|
MVKPipelineCache* _pipelineCache;
|
||||||
@ -468,7 +468,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
VkResult writeData(size_t* pDataSize, void* pData);
|
VkResult writeData(size_t* pDataSize, void* pData);
|
||||||
|
|
||||||
/** Return a shader library from the specified shader context sourced from the specified shader module. */
|
/** Return a shader library from the shader conversion configuration and sourced from the specified shader module. */
|
||||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConversionConfiguration* pContext, MVKShaderModule* shaderModule);
|
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConversionConfiguration* pContext, MVKShaderModule* shaderModule);
|
||||||
|
|
||||||
/** Merges the contents of the specified number of pipeline caches into this cache. */
|
/** Merges the contents of the specified number of pipeline caches into this cache. */
|
||||||
|
@ -187,7 +187,7 @@ void MVKPipeline::bindPushConstants(MVKCommandEncoder* cmdEncoder) {
|
|||||||
template<typename CreateInfo>
|
template<typename CreateInfo>
|
||||||
void MVKPipeline::addMTLArgumentEncoders(MVKMTLFunction& mvkMTLFunc,
|
void MVKPipeline::addMTLArgumentEncoders(MVKMTLFunction& mvkMTLFunc,
|
||||||
const CreateInfo* pCreateInfo,
|
const CreateInfo* pCreateInfo,
|
||||||
SPIRVToMSLConversionConfiguration& context,
|
SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||||
MVKShaderStage stage) {
|
MVKShaderStage stage) {
|
||||||
if ( !isUsingMetalArgumentBuffers() ) { return; }
|
if ( !isUsingMetalArgumentBuffers() ) { return; }
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ void MVKPipeline::addMTLArgumentEncoders(MVKMTLFunction& mvkMTLFunc,
|
|||||||
auto mtlFunc = mvkMTLFunc.getMTLFunction();
|
auto mtlFunc = mvkMTLFunc.getMTLFunction();
|
||||||
for (uint32_t dsIdx = 0; dsIdx < _descriptorSetCount; dsIdx++) {
|
for (uint32_t dsIdx = 0; dsIdx < _descriptorSetCount; dsIdx++) {
|
||||||
auto* dsLayout = ((MVKPipelineLayout*)pCreateInfo->layout)->getDescriptorSetLayout(dsIdx);
|
auto* dsLayout = ((MVKPipelineLayout*)pCreateInfo->layout)->getDescriptorSetLayout(dsIdx);
|
||||||
bool descSetIsUsed = dsLayout->populateBindingUse(getDescriptorBindingUse(dsIdx, stage), context, stage, dsIdx);
|
bool descSetIsUsed = dsLayout->populateBindingUse(getDescriptorBindingUse(dsIdx, stage), shaderConfig, stage, dsIdx);
|
||||||
if (descSetIsUsed && needMTLArgEnc) {
|
if (descSetIsUsed && needMTLArgEnc) {
|
||||||
getMTLArgumentEncoder(dsIdx, stage).init([mtlFunc newArgumentEncoderWithBufferIndex: dsIdx]);
|
getMTLArgumentEncoder(dsIdx, stage).init([mtlFunc newArgumentEncoderWithBufferIndex: dsIdx]);
|
||||||
}
|
}
|
||||||
@ -1577,10 +1577,10 @@ void MVKGraphicsPipeline::initShaderConversionConfig(SPIRVToMSLConversionConfigu
|
|||||||
shaderConfig.options.numTessControlPoints = reflectData.numControlPoints;
|
shaderConfig.options.numTessControlPoints = reflectData.numControlPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes the vertex attributes in a shader converter context.
|
// Initializes the vertex attributes in a shader conversion configuration.
|
||||||
void MVKGraphicsPipeline::addVertexInputToShaderConversionConfig(SPIRVToMSLConversionConfiguration& shaderConfig,
|
void MVKGraphicsPipeline::addVertexInputToShaderConversionConfig(SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||||
const VkGraphicsPipelineCreateInfo* pCreateInfo) {
|
const VkGraphicsPipelineCreateInfo* pCreateInfo) {
|
||||||
// Set the shader context vertex attribute information
|
// Set the shader conversion config vertex attribute information
|
||||||
shaderConfig.shaderInputs.clear();
|
shaderConfig.shaderInputs.clear();
|
||||||
uint32_t vaCnt = pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount;
|
uint32_t vaCnt = pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount;
|
||||||
for (uint32_t vaIdx = 0; vaIdx < vaCnt; vaIdx++) {
|
for (uint32_t vaIdx = 0; vaIdx < vaCnt; vaIdx++) {
|
||||||
@ -1629,10 +1629,10 @@ void MVKGraphicsPipeline::addVertexInputToShaderConversionConfig(SPIRVToMSLConve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes the shader inputs in a shader converter context from the previous stage output.
|
// Initializes the shader inputs in a shader conversion config from the previous stage output.
|
||||||
void MVKGraphicsPipeline::addPrevStageOutputToShaderConversionConfig(SPIRVToMSLConversionConfiguration& shaderConfig,
|
void MVKGraphicsPipeline::addPrevStageOutputToShaderConversionConfig(SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||||
SPIRVShaderOutputs& shaderOutputs) {
|
SPIRVShaderOutputs& shaderOutputs) {
|
||||||
// Set the shader context input variable information
|
// Set the shader conversion configuration input variable information
|
||||||
shaderConfig.shaderInputs.clear();
|
shaderConfig.shaderInputs.clear();
|
||||||
uint32_t siCnt = (uint32_t)shaderOutputs.size();
|
uint32_t siCnt = (uint32_t)shaderOutputs.size();
|
||||||
for (uint32_t siIdx = 0; siIdx < siCnt; siIdx++) {
|
for (uint32_t siIdx = 0; siIdx < siCnt; siIdx++) {
|
||||||
@ -1828,7 +1828,7 @@ MVKComputePipeline::~MVKComputePipeline() {
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKPipelineCache
|
#pragma mark MVKPipelineCache
|
||||||
|
|
||||||
// Return a shader library from the specified shader context sourced from the specified shader module.
|
// Return a shader library from the specified shader conversion configuration sourced from the specified shader module.
|
||||||
MVKShaderLibrary* MVKPipelineCache::getShaderLibrary(SPIRVToMSLConversionConfiguration* pContext, MVKShaderModule* shaderModule) {
|
MVKShaderLibrary* MVKPipelineCache::getShaderLibrary(SPIRVToMSLConversionConfiguration* pContext, MVKShaderModule* shaderModule) {
|
||||||
lock_guard<mutex> lock(_shaderCacheLock);
|
lock_guard<mutex> lock(_shaderCacheLock);
|
||||||
|
|
||||||
|
@ -128,13 +128,13 @@ public:
|
|||||||
MVKVulkanAPIObject* getVulkanAPIObject() override { return _owner->getVulkanAPIObject(); };
|
MVKVulkanAPIObject* getVulkanAPIObject() override { return _owner->getVulkanAPIObject(); };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a shader library from the specified shader context sourced from the specified shader module,
|
* Returns a shader library from the shader conversion configuration sourced from the shader module,
|
||||||
* lazily creating the shader library from source code in the shader module, if needed.
|
* lazily creating the shader library from source code in the shader module, if needed.
|
||||||
*
|
*
|
||||||
* If pWasAdded is not nil, this function will set it to true if a new shader library was created,
|
* If pWasAdded is not nil, this function will set it to true if a new shader library was created,
|
||||||
* and to false if an existing shader library was found and returned.
|
* and to false if an existing shader library was found and returned.
|
||||||
*/
|
*/
|
||||||
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConversionConfiguration* pContext,
|
MVKShaderLibrary* getShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig,
|
||||||
MVKShaderModule* shaderModule,
|
MVKShaderModule* shaderModule,
|
||||||
bool* pWasAdded = nullptr);
|
bool* pWasAdded = nullptr);
|
||||||
|
|
||||||
@ -147,8 +147,8 @@ protected:
|
|||||||
friend MVKPipelineCache;
|
friend MVKPipelineCache;
|
||||||
friend MVKShaderModule;
|
friend MVKShaderModule;
|
||||||
|
|
||||||
MVKShaderLibrary* findShaderLibrary(SPIRVToMSLConversionConfiguration* pContext);
|
MVKShaderLibrary* findShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig);
|
||||||
MVKShaderLibrary* addShaderLibrary(SPIRVToMSLConversionConfiguration* pContext,
|
MVKShaderLibrary* addShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig,
|
||||||
const std::string& mslSourceCode,
|
const std::string& mslSourceCode,
|
||||||
const SPIRVToMSLConversionResults& shaderConversionResults);
|
const SPIRVToMSLConversionResults& shaderConversionResults);
|
||||||
void merge(MVKShaderLibraryCache* other);
|
void merge(MVKShaderLibraryCache* other);
|
||||||
@ -195,12 +195,12 @@ public:
|
|||||||
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT; }
|
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT; }
|
||||||
|
|
||||||
/** Returns the Metal shader function, possibly specialized. */
|
/** Returns the Metal shader function, possibly specialized. */
|
||||||
MVKMTLFunction getMTLFunction(SPIRVToMSLConversionConfiguration* pContext,
|
MVKMTLFunction getMTLFunction(SPIRVToMSLConversionConfiguration* pShaderConfig,
|
||||||
const VkSpecializationInfo* pSpecializationInfo,
|
const VkSpecializationInfo* pSpecializationInfo,
|
||||||
MVKPipelineCache* pipelineCache);
|
MVKPipelineCache* pipelineCache);
|
||||||
|
|
||||||
/** Convert the SPIR-V to MSL, using the specified shader conversion context. */
|
/** Convert the SPIR-V to MSL, using the specified shader conversion configuration. */
|
||||||
bool convert(SPIRVToMSLConversionConfiguration* pContext);
|
bool convert(SPIRVToMSLConversionConfiguration* pShaderConfig);
|
||||||
|
|
||||||
/** Returns the original SPIR-V code that was specified when this object was created. */
|
/** Returns the original SPIR-V code that was specified when this object was created. */
|
||||||
const std::vector<uint32_t>& getSPIRV() { return _spvConverter.getSPIRV(); }
|
const std::vector<uint32_t>& getSPIRV() { return _spvConverter.getSPIRV(); }
|
||||||
@ -228,7 +228,7 @@ protected:
|
|||||||
friend MVKShaderCacheIterator;
|
friend MVKShaderCacheIterator;
|
||||||
|
|
||||||
void propagateDebugName() override {}
|
void propagateDebugName() override {}
|
||||||
MVKGLSLConversionShaderStage getMVKGLSLConversionShaderStage(SPIRVToMSLConversionConfiguration* pContext);
|
MVKGLSLConversionShaderStage getMVKGLSLConversionShaderStage(SPIRVToMSLConversionConfiguration* pShaderConfig);
|
||||||
|
|
||||||
MVKShaderLibraryCache _shaderLibraryCache;
|
MVKShaderLibraryCache _shaderLibraryCache;
|
||||||
SPIRVToMSLConverter _spvConverter;
|
SPIRVToMSLConverter _spvConverter;
|
||||||
|
@ -211,14 +211,14 @@ MVKShaderLibrary::~MVKShaderLibrary() {
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKShaderLibraryCache
|
#pragma mark MVKShaderLibraryCache
|
||||||
|
|
||||||
MVKShaderLibrary* MVKShaderLibraryCache::getShaderLibrary(SPIRVToMSLConversionConfiguration* pContext,
|
MVKShaderLibrary* MVKShaderLibraryCache::getShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig,
|
||||||
MVKShaderModule* shaderModule,
|
MVKShaderModule* shaderModule,
|
||||||
bool* pWasAdded) {
|
bool* pWasAdded) {
|
||||||
bool wasAdded = false;
|
bool wasAdded = false;
|
||||||
MVKShaderLibrary* shLib = findShaderLibrary(pContext);
|
MVKShaderLibrary* shLib = findShaderLibrary(pShaderConfig);
|
||||||
if ( !shLib ) {
|
if ( !shLib ) {
|
||||||
if (shaderModule->convert(pContext)) {
|
if (shaderModule->convert(pShaderConfig)) {
|
||||||
shLib = addShaderLibrary(pContext, shaderModule->getMSL(), shaderModule->getConversionResults());
|
shLib = addShaderLibrary(pShaderConfig, shaderModule->getMSL(), shaderModule->getConversionResults());
|
||||||
wasAdded = true;
|
wasAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,24 +228,24 @@ MVKShaderLibrary* MVKShaderLibraryCache::getShaderLibrary(SPIRVToMSLConversionCo
|
|||||||
return shLib;
|
return shLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finds and returns a shader library matching the specified context, or returns nullptr if it doesn't exist.
|
// Finds and returns a shader library matching the shader config, or returns nullptr if it doesn't exist.
|
||||||
// If a match is found, the specified context is aligned with the context of the matching library.
|
// If a match is found, the shader config is aligned with the shader config of the matching library.
|
||||||
MVKShaderLibrary* MVKShaderLibraryCache::findShaderLibrary(SPIRVToMSLConversionConfiguration* pContext) {
|
MVKShaderLibrary* MVKShaderLibraryCache::findShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig) {
|
||||||
for (auto& slPair : _shaderLibraries) {
|
for (auto& slPair : _shaderLibraries) {
|
||||||
if (slPair.first.matches(*pContext)) {
|
if (slPair.first.matches(*pShaderConfig)) {
|
||||||
pContext->alignWith(slPair.first);
|
pShaderConfig->alignWith(slPair.first);
|
||||||
return slPair.second;
|
return slPair.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds and returns a new shader library configured from the specified context.
|
// Adds and returns a new shader library configured from the specified conversion configuration.
|
||||||
MVKShaderLibrary* MVKShaderLibraryCache::addShaderLibrary(SPIRVToMSLConversionConfiguration* pContext,
|
MVKShaderLibrary* MVKShaderLibraryCache::addShaderLibrary(SPIRVToMSLConversionConfiguration* pShaderConfig,
|
||||||
const string& mslSourceCode,
|
const string& mslSourceCode,
|
||||||
const SPIRVToMSLConversionResults& shaderConversionResults) {
|
const SPIRVToMSLConversionResults& shaderConversionResults) {
|
||||||
MVKShaderLibrary* shLib = new MVKShaderLibrary(_owner, mslSourceCode, shaderConversionResults);
|
MVKShaderLibrary* shLib = new MVKShaderLibrary(_owner, mslSourceCode, shaderConversionResults);
|
||||||
_shaderLibraries.emplace_back(*pContext, shLib);
|
_shaderLibraries.emplace_back(*pShaderConfig, shLib);
|
||||||
return shLib;
|
return shLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ MVKShaderLibraryCache::~MVKShaderLibraryCache() {
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKShaderModule
|
#pragma mark MVKShaderModule
|
||||||
|
|
||||||
MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConversionConfiguration* pContext,
|
MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConversionConfiguration* pShaderConfig,
|
||||||
const VkSpecializationInfo* pSpecializationInfo,
|
const VkSpecializationInfo* pSpecializationInfo,
|
||||||
MVKPipelineCache* pipelineCache) {
|
MVKPipelineCache* pipelineCache) {
|
||||||
lock_guard<mutex> lock(_accessLock);
|
lock_guard<mutex> lock(_accessLock);
|
||||||
@ -277,20 +277,20 @@ MVKMTLFunction MVKShaderModule::getMTLFunction(SPIRVToMSLConversionConfiguration
|
|||||||
if ( !mvkLib ) {
|
if ( !mvkLib ) {
|
||||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||||
if (pipelineCache) {
|
if (pipelineCache) {
|
||||||
mvkLib = pipelineCache->getShaderLibrary(pContext, this);
|
mvkLib = pipelineCache->getShaderLibrary(pShaderConfig, this);
|
||||||
} else {
|
} else {
|
||||||
mvkLib = _shaderLibraryCache.getShaderLibrary(pContext, this);
|
mvkLib = _shaderLibraryCache.getShaderLibrary(pShaderConfig, this);
|
||||||
}
|
}
|
||||||
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.shaderLibraryFromCache, startTime);
|
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.shaderLibraryFromCache, startTime);
|
||||||
} else {
|
} else {
|
||||||
mvkLib->setEntryPointName(pContext->options.entryPointName);
|
mvkLib->setEntryPointName(pShaderConfig->options.entryPointName);
|
||||||
pContext->markAllInputsAndResourcesUsed();
|
pShaderConfig->markAllInputsAndResourcesUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mvkLib ? mvkLib->getMTLFunction(pSpecializationInfo, this) : MVKMTLFunctionNull;
|
return mvkLib ? mvkLib->getMTLFunction(pSpecializationInfo, this) : MVKMTLFunctionNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MVKShaderModule::convert(SPIRVToMSLConversionConfiguration* pContext) {
|
bool MVKShaderModule::convert(SPIRVToMSLConversionConfiguration* pShaderConfig) {
|
||||||
bool shouldLogCode = mvkConfig().debugMode;
|
bool shouldLogCode = mvkConfig().debugMode;
|
||||||
bool shouldLogEstimatedGLSL = shouldLogCode;
|
bool shouldLogEstimatedGLSL = shouldLogCode;
|
||||||
|
|
||||||
@ -299,7 +299,7 @@ bool MVKShaderModule::convert(SPIRVToMSLConversionConfiguration* pContext) {
|
|||||||
if ( !_spvConverter.hasSPIRV() && _glslConverter.hasGLSL() ) {
|
if ( !_spvConverter.hasSPIRV() && _glslConverter.hasGLSL() ) {
|
||||||
|
|
||||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||||
bool wasConverted = _glslConverter.convert(getMVKGLSLConversionShaderStage(pContext), shouldLogCode, false);
|
bool wasConverted = _glslConverter.convert(getMVKGLSLConversionShaderStage(pShaderConfig), shouldLogCode, false);
|
||||||
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.glslToSPRIV, startTime);
|
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.glslToSPRIV, startTime);
|
||||||
|
|
||||||
if (wasConverted) {
|
if (wasConverted) {
|
||||||
@ -312,7 +312,7 @@ bool MVKShaderModule::convert(SPIRVToMSLConversionConfiguration* pContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t startTime = _device->getPerformanceTimestamp();
|
uint64_t startTime = _device->getPerformanceTimestamp();
|
||||||
bool wasConverted = _spvConverter.convert(*pContext, shouldLogCode, shouldLogCode, shouldLogEstimatedGLSL);
|
bool wasConverted = _spvConverter.convert(*pShaderConfig, shouldLogCode, shouldLogCode, shouldLogEstimatedGLSL);
|
||||||
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.spirvToMSL, startTime);
|
_device->addActivityPerformance(_device->_performanceStatistics.shaderCompilation.spirvToMSL, startTime);
|
||||||
|
|
||||||
if (wasConverted) {
|
if (wasConverted) {
|
||||||
@ -323,9 +323,9 @@ bool MVKShaderModule::convert(SPIRVToMSLConversionConfiguration* pContext) {
|
|||||||
return wasConverted;
|
return wasConverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the MVKGLSLConversionShaderStage corresponding to the shader stage in the SPIR-V converter context.
|
// Returns the MVKGLSLConversionShaderStage corresponding to the shader stage in the SPIR-V conversion configuration.
|
||||||
MVKGLSLConversionShaderStage MVKShaderModule::getMVKGLSLConversionShaderStage(SPIRVToMSLConversionConfiguration* pContext) {
|
MVKGLSLConversionShaderStage MVKShaderModule::getMVKGLSLConversionShaderStage(SPIRVToMSLConversionConfiguration* pShaderConfig) {
|
||||||
switch (pContext->options.entryPointStage) {
|
switch (pShaderConfig->options.entryPointStage) {
|
||||||
case spv::ExecutionModelVertex: return kMVKGLSLConversionShaderStageVertex;
|
case spv::ExecutionModelVertex: return kMVKGLSLConversionShaderStageVertex;
|
||||||
case spv::ExecutionModelTessellationControl: return kMVKGLSLConversionShaderStageTessControl;
|
case spv::ExecutionModelTessellationControl: return kMVKGLSLConversionShaderStageTessControl;
|
||||||
case spv::ExecutionModelTessellationEvaluation: return kMVKGLSLConversionShaderStageTessEval;
|
case spv::ExecutionModelTessellationEvaluation: return kMVKGLSLConversionShaderStageTessEval;
|
||||||
|
@ -171,6 +171,11 @@ MVK_PUBLIC_SYMBOL void SPIRVToMSLConversionConfiguration::markAllInputsAndResour
|
|||||||
for (auto& rb : resourceBindings) { rb.outIsUsedByShader = true; }
|
for (auto& rb : resourceBindings) { rb.outIsUsedByShader = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A single SPIRVToMSLConversionConfiguration instance is used for all pipeline shader stages,
|
||||||
|
// and the resources can be spread across these shader stages. To improve cache hits when using
|
||||||
|
// this function to find a cached shader for a particular shader stage, only consider the resources
|
||||||
|
// that are used in that shader stage. By contrast, discreteDescriptorSet apply across all stages,
|
||||||
|
// and shaderInputs are populated before each stage, so neither needs to be filtered by stage here.
|
||||||
MVK_PUBLIC_SYMBOL bool SPIRVToMSLConversionConfiguration::matches(const SPIRVToMSLConversionConfiguration& other) const {
|
MVK_PUBLIC_SYMBOL bool SPIRVToMSLConversionConfiguration::matches(const SPIRVToMSLConversionConfiguration& other) const {
|
||||||
|
|
||||||
if ( !options.matches(other.options) ) { return false; }
|
if ( !options.matches(other.options) ) { return false; }
|
||||||
@ -180,17 +185,20 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConversionConfiguration::matches(const SPIRVToM
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& rb : resourceBindings) {
|
for (const auto& rb : resourceBindings) {
|
||||||
if (rb.outIsUsedByShader && !containsMatching(other.resourceBindings, rb)) { return false; }
|
if (rb.resourceBinding.stage == options.entryPointStage &&
|
||||||
|
rb.outIsUsedByShader &&
|
||||||
|
!containsMatching(other.resourceBindings, rb)) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& db : dynamicBufferDescriptors) {
|
||||||
|
if (db.stage == options.entryPointStage &&
|
||||||
|
!containsMatching(other.dynamicBufferDescriptors, db)) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t dsIdx : discreteDescriptorSets) {
|
for (uint32_t dsIdx : discreteDescriptorSets) {
|
||||||
if ( !contains(other.discreteDescriptorSets, dsIdx)) { return false; }
|
if ( !contains(other.discreteDescriptorSets, dsIdx)) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& db : dynamicBufferDescriptors) {
|
|
||||||
if ( !containsMatching(other.dynamicBufferDescriptors, db)) { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +234,7 @@ MVK_PUBLIC_SYMBOL void SPIRVToMSLConverter::setSPIRV(const uint32_t* spirvCode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfiguration& context,
|
MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||||
bool shouldLogSPIRV,
|
bool shouldLogSPIRV,
|
||||||
bool shouldLogMSL,
|
bool shouldLogMSL,
|
||||||
bool shouldLogGLSL) {
|
bool shouldLogGLSL) {
|
||||||
@ -250,36 +258,36 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfigur
|
|||||||
#endif
|
#endif
|
||||||
pMSLCompiler = new CompilerMSL(_spirv);
|
pMSLCompiler = new CompilerMSL(_spirv);
|
||||||
|
|
||||||
if (context.options.hasEntryPoint()) {
|
if (shaderConfig.options.hasEntryPoint()) {
|
||||||
pMSLCompiler->set_entry_point(context.options.entryPointName, context.options.entryPointStage);
|
pMSLCompiler->set_entry_point(shaderConfig.options.entryPointName, shaderConfig.options.entryPointStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up tessellation parameters if needed.
|
// Set up tessellation parameters if needed.
|
||||||
if (context.options.entryPointStage == ExecutionModelTessellationControl ||
|
if (shaderConfig.options.entryPointStage == ExecutionModelTessellationControl ||
|
||||||
context.options.entryPointStage == ExecutionModelTessellationEvaluation) {
|
shaderConfig.options.entryPointStage == ExecutionModelTessellationEvaluation) {
|
||||||
if (context.options.tessPatchKind != ExecutionModeMax) {
|
if (shaderConfig.options.tessPatchKind != ExecutionModeMax) {
|
||||||
pMSLCompiler->set_execution_mode(context.options.tessPatchKind);
|
pMSLCompiler->set_execution_mode(shaderConfig.options.tessPatchKind);
|
||||||
}
|
}
|
||||||
if (context.options.numTessControlPoints != 0) {
|
if (shaderConfig.options.numTessControlPoints != 0) {
|
||||||
pMSLCompiler->set_execution_mode(ExecutionModeOutputVertices, context.options.numTessControlPoints);
|
pMSLCompiler->set_execution_mode(ExecutionModeOutputVertices, shaderConfig.options.numTessControlPoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establish the MSL options for the compiler
|
// Establish the MSL options for the compiler
|
||||||
// This needs to be done in two steps...for CompilerMSL and its superclass.
|
// This needs to be done in two steps...for CompilerMSL and its superclass.
|
||||||
pMSLCompiler->set_msl_options(context.options.mslOptions);
|
pMSLCompiler->set_msl_options(shaderConfig.options.mslOptions);
|
||||||
|
|
||||||
auto scOpts = pMSLCompiler->get_common_options();
|
auto scOpts = pMSLCompiler->get_common_options();
|
||||||
scOpts.vertex.flip_vert_y = context.options.shouldFlipVertexY;
|
scOpts.vertex.flip_vert_y = shaderConfig.options.shouldFlipVertexY;
|
||||||
pMSLCompiler->set_common_options(scOpts);
|
pMSLCompiler->set_common_options(scOpts);
|
||||||
|
|
||||||
// Add shader inputs
|
// Add shader inputs
|
||||||
for (auto& si : context.shaderInputs) {
|
for (auto& si : shaderConfig.shaderInputs) {
|
||||||
pMSLCompiler->add_msl_shader_input(si.shaderInput);
|
pMSLCompiler->add_msl_shader_input(si.shaderInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add resource bindings and hardcoded constexpr samplers
|
// Add resource bindings and hardcoded constexpr samplers
|
||||||
for (auto& rb : context.resourceBindings) {
|
for (auto& rb : shaderConfig.resourceBindings) {
|
||||||
auto& rbb = rb.resourceBinding;
|
auto& rbb = rb.resourceBinding;
|
||||||
pMSLCompiler->add_msl_resource_binding(rbb);
|
pMSLCompiler->add_msl_resource_binding(rbb);
|
||||||
|
|
||||||
@ -290,15 +298,15 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfigur
|
|||||||
|
|
||||||
// Add any descriptor sets that are not using Metal argument buffers.
|
// Add any descriptor sets that are not using Metal argument buffers.
|
||||||
// This only has an effect if SPIRVToMSLConversionConfiguration::options::mslOptions::argument_buffers is enabled.
|
// This only has an effect if SPIRVToMSLConversionConfiguration::options::mslOptions::argument_buffers is enabled.
|
||||||
for (uint32_t dsIdx : context.discreteDescriptorSets) {
|
for (uint32_t dsIdx : shaderConfig.discreteDescriptorSets) {
|
||||||
pMSLCompiler->add_discrete_descriptor_set(dsIdx);
|
pMSLCompiler->add_discrete_descriptor_set(dsIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any dynamic buffer bindings.
|
// Add any dynamic buffer bindings.
|
||||||
// This only has an applies if SPIRVToMSLConversionConfiguration::options::mslOptions::argument_buffers is enabled.
|
// This only has an applies if SPIRVToMSLConversionConfiguration::options::mslOptions::argument_buffers is enabled.
|
||||||
if (context.options.mslOptions.argument_buffers) {
|
if (shaderConfig.options.mslOptions.argument_buffers) {
|
||||||
for (auto& db : context.dynamicBufferDescriptors) {
|
for (auto& db : shaderConfig.dynamicBufferDescriptors) {
|
||||||
if (db.stage == context.options.entryPointStage) {
|
if (db.stage == shaderConfig.options.entryPointStage) {
|
||||||
pMSLCompiler->add_dynamic_buffer(db.descriptorSet, db.binding, db.index);
|
pMSLCompiler->add_dynamic_buffer(db.descriptorSet, db.binding, db.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,7 +329,7 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfigur
|
|||||||
|
|
||||||
// Populate the shader conversion results with info from the compilation run,
|
// Populate the shader conversion results with info from the compilation run,
|
||||||
// and mark which vertex attributes and resource bindings are used by the shader
|
// and mark which vertex attributes and resource bindings are used by the shader
|
||||||
populateEntryPoint(pMSLCompiler, context.options);
|
populateEntryPoint(pMSLCompiler, shaderConfig.options);
|
||||||
_shaderConversionResults.isRasterizationDisabled = pMSLCompiler && pMSLCompiler->get_is_rasterization_disabled();
|
_shaderConversionResults.isRasterizationDisabled = pMSLCompiler && pMSLCompiler->get_is_rasterization_disabled();
|
||||||
_shaderConversionResults.isPositionInvariant = pMSLCompiler && pMSLCompiler->is_position_invariant();
|
_shaderConversionResults.isPositionInvariant = pMSLCompiler && pMSLCompiler->is_position_invariant();
|
||||||
_shaderConversionResults.needsSwizzleBuffer = pMSLCompiler && pMSLCompiler->needs_swizzle_buffer();
|
_shaderConversionResults.needsSwizzleBuffer = pMSLCompiler && pMSLCompiler->needs_swizzle_buffer();
|
||||||
@ -335,19 +343,19 @@ MVK_PUBLIC_SYMBOL bool SPIRVToMSLConverter::convert(SPIRVToMSLConversionConfigur
|
|||||||
// When using Metal argument buffers, if the shader is provided with dynamic buffer offsets,
|
// When using Metal argument buffers, if the shader is provided with dynamic buffer offsets,
|
||||||
// then it needs a buffer to hold these dynamic offsets.
|
// then it needs a buffer to hold these dynamic offsets.
|
||||||
_shaderConversionResults.needsDynamicOffsetBuffer = false;
|
_shaderConversionResults.needsDynamicOffsetBuffer = false;
|
||||||
if (context.options.mslOptions.argument_buffers) {
|
if (shaderConfig.options.mslOptions.argument_buffers) {
|
||||||
for (auto& db : context.dynamicBufferDescriptors) {
|
for (auto& db : shaderConfig.dynamicBufferDescriptors) {
|
||||||
if (db.stage == context.options.entryPointStage) {
|
if (db.stage == shaderConfig.options.entryPointStage) {
|
||||||
_shaderConversionResults.needsDynamicOffsetBuffer = true;
|
_shaderConversionResults.needsDynamicOffsetBuffer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& ctxSI : context.shaderInputs) {
|
for (auto& ctxSI : shaderConfig.shaderInputs) {
|
||||||
ctxSI.outIsUsedByShader = pMSLCompiler->is_msl_shader_input_used(ctxSI.shaderInput.location);
|
ctxSI.outIsUsedByShader = pMSLCompiler->is_msl_shader_input_used(ctxSI.shaderInput.location);
|
||||||
}
|
}
|
||||||
for (auto& ctxRB : context.resourceBindings) {
|
for (auto& ctxRB : shaderConfig.resourceBindings) {
|
||||||
if (ctxRB.resourceBinding.stage == context.options.entryPointStage) {
|
if (ctxRB.resourceBinding.stage == shaderConfig.options.entryPointStage) {
|
||||||
ctxRB.outIsUsedByShader = pMSLCompiler->is_msl_resource_binding_used(ctxRB.resourceBinding.stage,
|
ctxRB.outIsUsedByShader = pMSLCompiler->is_msl_resource_binding_used(ctxRB.resourceBinding.stage,
|
||||||
ctxRB.resourceBinding.desc_set,
|
ctxRB.resourceBinding.desc_set,
|
||||||
ctxRB.resourceBinding.binding);
|
ctxRB.resourceBinding.binding);
|
||||||
|
@ -171,15 +171,15 @@ namespace mvk {
|
|||||||
void markAllInputsAndResourcesUsed();
|
void markAllInputsAndResourcesUsed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this configuration matches the other context. It does if the
|
* Returns whether this configuration matches the other configuration. It does if
|
||||||
* respective options match and any vertex attributes and resource bindings used
|
* the respective options match and any vertex attributes and resource bindings used
|
||||||
* by this configuration can be found in the other configuration. Vertex attributes
|
* by this configuration can be found in the other configuration. Vertex attributes
|
||||||
* and resource bindings that are in the other configuration but are not used by
|
* and resource bindings that are in the other configuration but are not used by
|
||||||
* the shader that created this configuration, are ignored.
|
* the shader that created this configuration, are ignored.
|
||||||
*/
|
*/
|
||||||
bool matches(const SPIRVToMSLConversionConfiguration& other) const;
|
bool matches(const SPIRVToMSLConversionConfiguration& other) const;
|
||||||
|
|
||||||
/** Aligns certain aspects of this configuration with the source context. */
|
/** Aligns certain aspects of this configuration with the source configuration. */
|
||||||
void alignWith(const SPIRVToMSLConversionConfiguration& srcContext);
|
void alignWith(const SPIRVToMSLConversionConfiguration& srcContext);
|
||||||
|
|
||||||
} SPIRVToMSLConversionConfiguration;
|
} SPIRVToMSLConversionConfiguration;
|
||||||
@ -274,7 +274,7 @@ namespace mvk {
|
|||||||
* and optionally, the original GLSL (as converted from the SPIR_V), should be logged
|
* and optionally, the original GLSL (as converted from the SPIR_V), should be logged
|
||||||
* to the result log of this converter. This can be useful during shader debugging.
|
* to the result log of this converter. This can be useful during shader debugging.
|
||||||
*/
|
*/
|
||||||
bool convert(SPIRVToMSLConversionConfiguration& context,
|
bool convert(SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||||
bool shouldLogSPIRV = false,
|
bool shouldLogSPIRV = false,
|
||||||
bool shouldLogMSL = false,
|
bool shouldLogMSL = false,
|
||||||
bool shouldLogGLSL = false);
|
bool shouldLogGLSL = false);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user