Construct MTLArgumentEncoders for pipelines.
MVKPipeline tracks a MTLArgumentEncoder for each descriptor set in the pipeline layout, created from MTLArgumentDescriptors that are populated by MVKDescriptorSetLayoutBindings in each MVKDescriptorSetLayout.
This commit is contained in:
parent
751d864964
commit
14c649853f
@ -83,7 +83,7 @@ public:
|
||||
* count provided to that descriptor set is returned. Otherwise returns the value
|
||||
* defined in VkDescriptorSetLayoutBinding::descriptorCount.
|
||||
*/
|
||||
uint32_t getDescriptorCount(MVKDescriptorSet* descSet);
|
||||
uint32_t getDescriptorCount(MVKDescriptorSet* descSet = nullptr);
|
||||
|
||||
/** Returns the descriptor type of this layout. */
|
||||
inline VkDescriptorType getDescriptorType() { return _info.descriptorType; }
|
||||
@ -129,6 +129,15 @@ protected:
|
||||
MVKShaderStageResourceBinding* pDescSetCounts,
|
||||
const VkDescriptorSetLayoutBinding* pBinding);
|
||||
void initMetalArgumentBufferIndexes(uint32_t& argIdx, NSUInteger& argBuffSize);
|
||||
void addMTLArgumentDescriptors(NSMutableArray<MTLArgumentDescriptor*>* args,
|
||||
mvk::SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||
uint32_t descSetIdx);
|
||||
void addMTLArgumentDescriptor(NSMutableArray<MTLArgumentDescriptor*>* args,
|
||||
MTLDataType dataType,
|
||||
MTLArgumentAccess access,
|
||||
mvk::SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||
uint32_t descSetIdx,
|
||||
uint32_t argIdxOffset = 0);
|
||||
void populateShaderConverterContext(mvk::SPIRVToMSLConversionConfiguration& context,
|
||||
MVKShaderResourceBinding& dslMTLRezIdxOffsets,
|
||||
uint32_t dslIndex);
|
||||
|
@ -340,7 +340,7 @@ void MVKDescriptorSetLayoutBinding::initMetalArgumentBufferIndexes(uint32_t& arg
|
||||
|
||||
_metalArgumentBufferIndex = argIdx;
|
||||
|
||||
uint32_t descCnt = getDescriptorCount(nullptr);
|
||||
uint32_t descCnt = getDescriptorCount();
|
||||
switch (getDescriptorType()) {
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
@ -384,13 +384,71 @@ void MVKDescriptorSetLayoutBinding::initMetalArgumentBufferIndexes(uint32_t& arg
|
||||
}
|
||||
}
|
||||
|
||||
// If depth compare is required, but unavailable on the device, the sampler can only be used as an immutable sampler
|
||||
bool MVKDescriptorSetLayoutBinding::validate(MVKSampler* mvkSampler) {
|
||||
if (mvkSampler->getRequiresConstExprSampler()) {
|
||||
mvkSampler->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdPushDescriptorSet/vkCmdPushDescriptorSetWithTemplate(): Tried to push an immutable sampler.");
|
||||
return false;
|
||||
// Adds MTLArgumentDescriptors to the array, and updates resource indexes consumed.
|
||||
void MVKDescriptorSetLayoutBinding::addMTLArgumentDescriptors(NSMutableArray<MTLArgumentDescriptor*>* args,
|
||||
mvk::SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||
uint32_t descSetIdx) {
|
||||
switch (getDescriptorType()) {
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypePointer, MTLArgumentAccessReadOnly, shaderConfig, descSetIdx);
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypePointer, MTLArgumentAccessReadWrite, shaderConfig, descSetIdx);
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypeTexture, MTLArgumentAccessReadOnly, shaderConfig, descSetIdx);
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypeTexture, MTLArgumentAccessReadWrite, shaderConfig, descSetIdx);
|
||||
addMTLArgumentDescriptor(args, MTLDataTypePointer, MTLArgumentAccessReadWrite, shaderConfig, descSetIdx, getDescriptorCount()); // Needed for atomic operations
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypeTexture, MTLArgumentAccessReadOnly, shaderConfig, descSetIdx);
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypeTexture, MTLArgumentAccessReadWrite, shaderConfig, descSetIdx);
|
||||
addMTLArgumentDescriptor(args, MTLDataTypePointer, MTLArgumentAccessReadWrite, shaderConfig, descSetIdx, getDescriptorCount()); // Needed for atomic operations
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypeSampler, MTLArgumentAccessReadOnly, shaderConfig, descSetIdx);
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
addMTLArgumentDescriptor(args, MTLDataTypeTexture, MTLArgumentAccessReadOnly, shaderConfig, descSetIdx);
|
||||
addMTLArgumentDescriptor(args, MTLDataTypeSampler, MTLArgumentAccessReadOnly, shaderConfig, descSetIdx, getDescriptorCount());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds an MTLArgumentDescriptor if the specified type to the array, and updates resource indexes consumed.
|
||||
void MVKDescriptorSetLayoutBinding::addMTLArgumentDescriptor(NSMutableArray<MTLArgumentDescriptor*>* args,
|
||||
MTLDataType dataType,
|
||||
MTLArgumentAccess access,
|
||||
mvk::SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||
uint32_t descSetIdx,
|
||||
uint32_t argIdxOffset) {
|
||||
auto* argDesc = [MTLArgumentDescriptor argumentDescriptor];
|
||||
argDesc.dataType = dataType;
|
||||
argDesc.access = access;
|
||||
argDesc.index = _metalArgumentBufferIndex + argIdxOffset;
|
||||
argDesc.arrayLength = getDescriptorCount();
|
||||
argDesc.textureType = shaderConfig.getMTLTextureType(descSetIdx, getBinding());
|
||||
|
||||
[args addObject: argDesc];
|
||||
}
|
||||
|
||||
void MVKDescriptorSetLayoutBinding::populateShaderConverterContext(mvk::SPIRVToMSLConversionConfiguration& context,
|
||||
@ -416,12 +474,21 @@ void MVKDescriptorSetLayoutBinding::populateShaderConverterContext(mvk::SPIRVToM
|
||||
models[i],
|
||||
dslIndex,
|
||||
_info.binding,
|
||||
getDescriptorCount(nullptr),
|
||||
getDescriptorCount(),
|
||||
mvkSamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If depth compare is required, but unavailable on the device, the sampler can only be used as an immutable sampler
|
||||
bool MVKDescriptorSetLayoutBinding::validate(MVKSampler* mvkSampler) {
|
||||
if (mvkSampler->getRequiresConstExprSampler()) {
|
||||
mvkSampler->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdPushDescriptorSet/vkCmdPushDescriptorSetWithTemplate(): Tried to push an immutable sampler.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDevice* device,
|
||||
MVKDescriptorSetLayout* layout,
|
||||
const VkDescriptorSetLayoutBinding* pBinding,
|
||||
|
@ -75,6 +75,9 @@ public:
|
||||
/** Returns whether this layout is using an argument buffer. */
|
||||
inline bool isUsingMetalArgumentBuffer() { return isUsingMetalArgumentBuffers() && !isPushDescriptorLayout(); };
|
||||
|
||||
/** Returns a new MTLArgumentEncoder for the stage, populated from this layout and info from the shader config. */
|
||||
id<MTLArgumentEncoder> newMTLArgumentEncoder(mvk::SPIRVToMSLConversionConfiguration& shaderConfig, uint32_t descSetIdx);
|
||||
|
||||
MVKDescriptorSetLayout(MVKDevice* device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo);
|
||||
|
||||
protected:
|
||||
|
@ -173,6 +173,17 @@ void MVKDescriptorSetLayout::populateShaderConverterContext(mvk::SPIRVToMSLConve
|
||||
}
|
||||
}
|
||||
|
||||
id<MTLArgumentEncoder> MVKDescriptorSetLayout::newMTLArgumentEncoder(mvk::SPIRVToMSLConversionConfiguration& shaderConfig,
|
||||
uint32_t descSetIdx) {
|
||||
@autoreleasepool {
|
||||
NSMutableArray<MTLArgumentDescriptor*>* args = [NSMutableArray arrayWithCapacity: _bindings.size()];
|
||||
for (auto& dslBind : _bindings) {
|
||||
dslBind.addMTLArgumentDescriptors(args, shaderConfig, descSetIdx);
|
||||
}
|
||||
return (args.count) ? [getMTLDevice() newArgumentEncoderWithArguments: args] : nil;
|
||||
}
|
||||
}
|
||||
|
||||
MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
|
||||
const VkDescriptorSetLayoutCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
|
||||
|
||||
@ -202,7 +213,7 @@ MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
|
||||
BindInfo& bindInfo = sortedBindings[bindIdx];
|
||||
_bindings.emplace_back(_device, this, bindInfo.pBinding, bindInfo.bindingFlags, _descriptorCount);
|
||||
_bindingToIndex[bindInfo.pBinding->binding] = bindIdx;
|
||||
_descriptorCount += _bindings.back().getDescriptorCount(nullptr);
|
||||
_descriptorCount += _bindings.back().getDescriptorCount();
|
||||
}
|
||||
|
||||
initMetalArgumentBufferIndexes();
|
||||
|
@ -100,6 +100,9 @@ public:
|
||||
/** Returns the number of buffers in this layout. This is used to calculate the size of the buffer size buffer. */
|
||||
uint32_t getBufferCount() { return _pushConstantsMTLResourceIndexes.getMaxBufferIndex(); }
|
||||
|
||||
/** Returns the number of descriptor sets in this pipeline layout. */
|
||||
uint32_t getDescriptorSetCount() { return (uint32_t)_descriptorSetLayouts.size(); }
|
||||
|
||||
/** Returns the push constant binding info. */
|
||||
const MVKShaderResourceBinding& getPushConstantBindings() { return _pushConstantsMTLResourceIndexes; }
|
||||
|
||||
@ -109,6 +112,8 @@ public:
|
||||
~MVKPipelineLayout() override;
|
||||
|
||||
protected:
|
||||
friend class MVKPipeline;
|
||||
|
||||
void propagateDebugName() override {}
|
||||
|
||||
MVKSmallVector<MVKDescriptorSetLayout*, 1> _descriptorSetLayouts;
|
||||
@ -173,8 +178,13 @@ public:
|
||||
|
||||
protected:
|
||||
void propagateDebugName() override {}
|
||||
void addMTLArgumentEncoders(MVKPipelineLayout* layout, SPIRVToMSLConversionConfiguration& shaderConfig);
|
||||
id<MTLArgumentEncoder> getMTLArgumentEncoder(uint32_t descSetIdx) {
|
||||
return descSetIdx < _mtlArgumentEncoders.size() ? _mtlArgumentEncoders[descSetIdx] : nil;
|
||||
}
|
||||
|
||||
MVKPipelineCache* _pipelineCache;
|
||||
MVKSmallVector<id<MTLArgumentEncoder>> _mtlArgumentEncoders;
|
||||
MVKShaderImplicitRezBinding _swizzleBufferIndex;
|
||||
MVKShaderImplicitRezBinding _bufferSizeBufferIndex;
|
||||
MVKShaderImplicitRezBinding _indirectParamsIndex;
|
||||
|
@ -79,7 +79,7 @@ void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConversionConfi
|
||||
context.discreteDescriptorSets.clear();
|
||||
|
||||
// Add resource bindings defined in the descriptor set layouts
|
||||
uint32_t dslCnt = (uint32_t)_descriptorSetLayouts.size();
|
||||
uint32_t dslCnt = getDescriptorSetCount();
|
||||
for (uint32_t dslIdx = 0; dslIdx < dslCnt; dslIdx++) {
|
||||
_descriptorSetLayouts[dslIdx]->populateShaderConverterContext(context,
|
||||
_dslMTLResourceIndexOffsets[dslIdx],
|
||||
@ -169,11 +169,19 @@ void MVKPipeline::bindPushConstants(MVKCommandEncoder* cmdEncoder) {
|
||||
}
|
||||
}
|
||||
|
||||
void MVKPipeline::addMTLArgumentEncoders(MVKPipelineLayout* layout, SPIRVToMSLConversionConfiguration& shaderConfig) {
|
||||
uint32_t dsCnt = layout->getDescriptorSetCount();
|
||||
for (uint32_t dsIdx = 0; dsIdx < dsCnt; dsIdx++) {
|
||||
_mtlArgumentEncoders[dsIdx] = layout->_descriptorSetLayouts[dsIdx]->newMTLArgumentEncoder(shaderConfig, dsIdx);
|
||||
}
|
||||
}
|
||||
|
||||
MVKPipeline::MVKPipeline(MVKDevice* device, MVKPipelineCache* pipelineCache, MVKPipelineLayout* layout, MVKPipeline* parent) :
|
||||
MVKVulkanAPIDeviceObject(device),
|
||||
_pipelineCache(pipelineCache),
|
||||
_pushConstantsMTLResourceIndexes(layout->getPushConstantBindings()),
|
||||
_fullImageViewSwizzle(mvkConfig()->fullImageViewSwizzle) {}
|
||||
_fullImageViewSwizzle(mvkConfig()->fullImageViewSwizzle),
|
||||
_mtlArgumentEncoders(layout->getDescriptorSetCount()) {}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
@ -523,6 +531,8 @@ void MVKGraphicsPipeline::initMTLRenderPipelineState(const VkGraphicsPipelineCre
|
||||
}
|
||||
[tcPLDesc release]; // temp release
|
||||
[rastPLDesc release]; // temp release
|
||||
|
||||
addMTLArgumentEncoders((MVKPipelineLayout*)pCreateInfo->layout, shaderContext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,10 +565,13 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::newMTLRenderPipelineDescriptor
|
||||
// Output
|
||||
addFragmentOutputToPipeline(plDesc, pCreateInfo);
|
||||
|
||||
MVKPipelineLayout* layout = (MVKPipelineLayout*)pCreateInfo->layout;
|
||||
addMTLArgumentEncoders(layout, shaderContext);
|
||||
|
||||
// Metal does not allow the name of the pipeline to be changed after it has been created,
|
||||
// and we need to create the Metal pipeline immediately to provide error feedback to app.
|
||||
// The best we can do at this point is set the pipeline name from the layout.
|
||||
setLabelIfNotNil(plDesc, ((MVKPipelineLayout*)pCreateInfo->layout)->getDebugName());
|
||||
setLabelIfNotNil(plDesc, layout->getDebugName());
|
||||
|
||||
return plDesc;
|
||||
}
|
||||
@ -1717,6 +1730,8 @@ MVKMTLFunction MVKComputePipeline::getMTLFunction(const VkComputePipelineCreateI
|
||||
_needsBufferSizeBuffer = funcRslts.needsBufferSizeBuffer;
|
||||
_needsDispatchBaseBuffer = funcRslts.needsDispatchBaseBuffer;
|
||||
|
||||
addMTLArgumentEncoders(layout, shaderContext);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user