Initial support for handling VK_EXT_descriptor_indexing structures.

VK_EXT_descriptor_indexing adds no new functions, but does add six structures to
existing pNext chains. This initial commit processes these structs, but does not
yet perform any operational functionality for this extension.
This commit is contained in:
Bill Hollings 2020-10-27 11:32:06 -04:00
parent bc8bb0453f
commit 794edc5ec1
10 changed files with 262 additions and 29 deletions

View File

@ -303,6 +303,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_EXT_debug_marker`
- `VK_EXT_debug_report`
- `VK_EXT_debug_utils`
- `VK_EXT_descriptor_indexing`
- `VK_EXT_fragment_shader_interlock` *(requires Metal 2.0 and Raster Order Groups)*
- `VK_EXT_host_query_reset`
- `VK_EXT_image_robustness`

View File

@ -19,6 +19,7 @@ MoltenVK 1.1.1
Released TBD
- Add support for extensions:
- `VK_EXT_descriptor_indexing`
- `VK_EXT_private_data`
- Use `VK_KHR_image_format_list` to disable `MTLTextureUsagePixelFormatView`
if only swizzles or `sRGB` conversion will be used for image views, improving

View File

@ -110,7 +110,8 @@ public:
MVKDescriptorSetLayoutBinding(MVKDevice* device,
MVKDescriptorSetLayout* layout,
const VkDescriptorSetLayoutBinding* pBinding);
const VkDescriptorSetLayoutBinding* pBinding,
VkDescriptorBindingFlagsEXT bindingFlags);
MVKDescriptorSetLayoutBinding(const MVKDescriptorSetLayoutBinding& binding);
@ -125,6 +126,7 @@ protected:
MVKDescriptorSetLayout* _layout;
VkDescriptorSetLayoutBinding _info;
VkDescriptorBindingFlagsEXT _flags;
MVKSmallVector<MVKSampler*> _immutableSamplers;
MVKShaderResourceBinding _mtlResourceIndexOffsets;
bool _applyToStage[kMVKShaderStageMax];

View File

@ -359,8 +359,15 @@ void MVKDescriptorSetLayoutBinding::populateShaderConverterContext(mvk::SPIRVToM
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDevice* device,
MVKDescriptorSetLayout* layout,
const VkDescriptorSetLayoutBinding* pBinding) : MVKBaseDeviceObject(device), _layout(layout),
_dynamicOffsetIndex(0) {
const VkDescriptorSetLayoutBinding* pBinding,
VkDescriptorBindingFlagsEXT bindingFlags) :
MVKBaseDeviceObject(device),
_layout(layout),
_info(*pBinding),
_flags(bindingFlags),
_dynamicOffsetIndex(0) {
_info.pImmutableSamplers = nullptr; // Remove dangling pointer
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
// Determine if this binding is used by this shader stage
@ -383,13 +390,14 @@ MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(MVKDevice* device,
}
}
_info = *pBinding;
_info.pImmutableSamplers = nullptr; // Remove dangling pointer
}
MVKDescriptorSetLayoutBinding::MVKDescriptorSetLayoutBinding(const MVKDescriptorSetLayoutBinding& binding) :
MVKBaseDeviceObject(binding._device), _layout(binding._layout),
_info(binding._info), _immutableSamplers(binding._immutableSamplers),
MVKBaseDeviceObject(binding._device),
_layout(binding._layout),
_info(binding._info),
_flags(binding._flags),
_immutableSamplers(binding._immutableSamplers),
_mtlResourceIndexOffsets(binding._mtlResourceIndexOffsets),
_dynamicOffsetIndex(0) {

View File

@ -87,6 +87,7 @@ protected:
inline uint32_t getDescriptorCount() { return _descriptorCount; }
inline uint32_t getDescriptorIndex(uint32_t binding, uint32_t elementIndex = 0) { return _bindingToDescriptorIndex[binding] + elementIndex; }
inline MVKDescriptorSetLayoutBinding* getBinding(uint32_t binding) { return &_bindings[_bindingToIndex[binding]]; }
const VkDescriptorBindingFlags* getBindingFlags(const VkDescriptorSetLayoutCreateInfo* pCreateInfo);
MVKSmallVector<MVKDescriptorSetLayoutBinding> _bindings;
std::unordered_map<uint32_t, uint32_t> _bindingToIndex;
@ -129,7 +130,9 @@ public:
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock);
MVKDescriptorSet(MVKDescriptorSetLayout* layout, MVKDescriptorPool* pool);
MVKDescriptorSet(MVKDescriptorSetLayout* layout,
uint32_t variableDescriptorCount,
MVKDescriptorPool* pool);
~MVKDescriptorSet() override;
@ -143,6 +146,7 @@ protected:
MVKDescriptorSetLayout* _layout;
MVKDescriptorPool* _pool;
MVKSmallVector<MVKDescriptor*> _descriptors;
uint32_t _variableDescriptorCount;
};
@ -225,9 +229,8 @@ public:
/** Returns the debug report object type of this object. */
VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT; }
/** Allocates the specified number of descriptor sets. */
VkResult allocateDescriptorSets(uint32_t count,
const VkDescriptorSetLayout* pSetLayouts,
/** Allocates descriptor sets. */
VkResult allocateDescriptorSets(const VkDescriptorSetAllocateInfo* pAllocateInfo,
VkDescriptorSet* pDescriptorSets);
/** Free's up the specified descriptor set. */
@ -244,7 +247,8 @@ protected:
friend class MVKDescriptorSet;
void propagateDebugName() override {}
VkResult allocateDescriptorSet(MVKDescriptorSetLayout* mvkDSL, VkDescriptorSet* pVKDS);
VkResult allocateDescriptorSet(MVKDescriptorSetLayout* mvkDSL, uint32_t variableDescriptorCount, VkDescriptorSet* pVKDS);
const uint32_t* getVariableDecriptorCounts(const VkDescriptorSetAllocateInfo* pAllocateInfo);
void freeDescriptorSet(MVKDescriptorSet* mvkDS);
VkResult allocateDescriptor(VkDescriptorType descriptorType, MVKDescriptor** pMVKDesc);
void freeDescriptor(MVKDescriptor* mvkDesc);

View File

@ -170,14 +170,14 @@ void MVKDescriptorSetLayout::populateShaderConverterContext(mvk::SPIRVToMSLConve
MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
const VkDescriptorSetLayoutCreateInfo* pCreateInfo) : MVKVulkanAPIDeviceObject(device) {
const auto* pBindingFlags = getBindingFlags(pCreateInfo);
_isPushDescriptorLayout = (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) != 0;
_descriptorCount = 0;
_bindings.reserve(pCreateInfo->bindingCount);
MVKSmallVector<MVKDescriptorSetLayoutBinding*, 32> dynamicBindings;
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
auto* pBind = &pCreateInfo->pBindings[i];
_bindings.emplace_back(_device, this, pBind);
_bindings.emplace_back(_device, this, pBind, (pBindingFlags ? pBindingFlags[i] : 0));
_bindingToIndex[pBind->binding] = i;
_bindingToDescriptorIndex[pBind->binding] = _descriptorCount;
@ -203,6 +203,22 @@ MVKDescriptorSetLayout::MVKDescriptorSetLayout(MVKDevice* device,
}
}
// Find and return an array of binding flags from the pNext chain of pCreateInfo,
// or return nullptr if the chain does not include binding flags.
const VkDescriptorBindingFlags* MVKDescriptorSetLayout::getBindingFlags(const VkDescriptorSetLayoutCreateInfo* pCreateInfo) {
for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT: {
auto* pDescSetLayoutBindingFlags = (VkDescriptorSetLayoutBindingFlagsCreateInfoEXT*)next;
return pDescSetLayoutBindingFlags->bindingCount ? pDescSetLayoutBindingFlags->pBindingFlags : nullptr;
}
default:
break;
}
}
return nullptr;
}
#pragma mark -
#pragma mark MVKDescriptorSet
@ -261,9 +277,13 @@ void MVKDescriptorSet::read(const VkCopyDescriptorSet* pDescriptorCopy,
}
}
// If the descriptor pool fails to allocate a descriptor, record a configuration error
MVKDescriptorSet::MVKDescriptorSet(MVKDescriptorSetLayout* layout, MVKDescriptorPool* pool) :
MVKVulkanAPIDeviceObject(pool->_device), _layout(layout), _pool(pool) {
MVKDescriptorSet::MVKDescriptorSet(MVKDescriptorSetLayout* layout,
uint32_t variableDescriptorCount,
MVKDescriptorPool* pool) :
MVKVulkanAPIDeviceObject(pool->_device),
_layout(layout),
_variableDescriptorCount(variableDescriptorCount),
_pool(pool) {
_descriptors.reserve(layout->getDescriptorCount());
uint32_t bindCnt = (uint32_t)layout->_bindings.size();
@ -532,10 +552,9 @@ MVKPreallocatedDescriptors::MVKPreallocatedDescriptors(const VkDescriptorPoolCre
#pragma mark -
#pragma mark MVKDescriptorPool
VkResult MVKDescriptorPool::allocateDescriptorSets(uint32_t count,
const VkDescriptorSetLayout* pSetLayouts,
VkResult MVKDescriptorPool::allocateDescriptorSets(const VkDescriptorSetAllocateInfo* pAllocateInfo,
VkDescriptorSet* pDescriptorSets) {
if (_allocatedSets.size() + count > _maxSets) {
if (_allocatedSets.size() + pAllocateInfo->descriptorSetCount > _maxSets) {
if (_device->_enabledExtensions.vk_KHR_maintenance1.enabled ||
_device->getInstance()->getAPIVersion() >= VK_API_VERSION_1_1) {
return VK_ERROR_OUT_OF_POOL_MEMORY; // Failure is an acceptable test...don't log as error.
@ -545,16 +564,33 @@ VkResult MVKDescriptorPool::allocateDescriptorSets(uint32_t count,
}
VkResult rslt = VK_SUCCESS;
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
MVKDescriptorSetLayout* mvkDSL = (MVKDescriptorSetLayout*)pSetLayouts[dsIdx];
const auto* pVarDescCounts = getVariableDecriptorCounts(pAllocateInfo);
for (uint32_t dsIdx = 0; dsIdx < pAllocateInfo->descriptorSetCount; dsIdx++) {
MVKDescriptorSetLayout* mvkDSL = (MVKDescriptorSetLayout*)pAllocateInfo->pSetLayouts[dsIdx];
if ( !mvkDSL->isPushDescriptorLayout() ) {
rslt = allocateDescriptorSet(mvkDSL, &pDescriptorSets[dsIdx]);
rslt = allocateDescriptorSet(mvkDSL, (pVarDescCounts ? pVarDescCounts[dsIdx] : 0), &pDescriptorSets[dsIdx]);
if (rslt) { break; }
}
}
return rslt;
}
// Find and return an array of variable descriptor counts from the pNext chain of pCreateInfo,
// or return nullptr if the chain does not include variable descriptor counts.
const uint32_t* MVKDescriptorPool::getVariableDecriptorCounts(const VkDescriptorSetAllocateInfo* pAllocateInfo) {
for (const auto* next = (VkBaseInStructure*)pAllocateInfo->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT: {
auto* pVarDescSetVarCounts = (VkDescriptorSetVariableDescriptorCountAllocateInfoEXT*)next;
return pVarDescSetVarCounts->descriptorSetCount ? pVarDescSetVarCounts->pDescriptorCounts : nullptr;
}
default:
break;
}
}
return nullptr;
}
// Ensure descriptor set was actually allocated, then return to pool
VkResult MVKDescriptorPool::freeDescriptorSets(uint32_t count, const VkDescriptorSet* pDescriptorSets) {
for (uint32_t dsIdx = 0; dsIdx < count; dsIdx++) {
@ -575,8 +611,9 @@ VkResult MVKDescriptorPool::reset(VkDescriptorPoolResetFlags flags) {
}
VkResult MVKDescriptorPool::allocateDescriptorSet(MVKDescriptorSetLayout* mvkDSL,
uint32_t variableDescriptorCount,
VkDescriptorSet* pVKDS) {
MVKDescriptorSet* mvkDS = new MVKDescriptorSet(mvkDSL, this);
MVKDescriptorSet* mvkDS = new MVKDescriptorSet(mvkDSL, variableDescriptorCount, this);
VkResult rslt = mvkDS->getConfigurationResult();
if (mvkDS->wasConfigurationSuccessful()) {

View File

@ -680,6 +680,7 @@ public:
const VkPhysicalDeviceFloat16Int8FeaturesKHR _enabledF16I8Features;
const VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR _enabledUBOLayoutFeatures;
const VkPhysicalDeviceVariablePointerFeatures _enabledVarPtrFeatures;
const VkPhysicalDeviceDescriptorIndexingFeaturesEXT _enabledDescriptorIndexingFeatures;
const VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT _enabledInterlockFeatures;
const VkPhysicalDeviceHostQueryResetFeaturesEXT _enabledHostQryResetFeatures;
const VkPhysicalDeviceSamplerYcbcrConversionFeatures _enabledSamplerYcbcrConversionFeatures;
@ -741,6 +742,9 @@ protected:
const char* getActivityPerformanceDescription(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats);
void logActivityPerformance(MVKPerformanceTracker& activity, MVKPerformanceStatistics& perfStats, bool isInline = false);
void updateActivityPerformance(MVKPerformanceTracker& activity, uint64_t startTime, uint64_t endTime);
void getDescriptorVariableDescriptorCountLayoutSupport(const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
VkDescriptorSetLayoutSupport* pSupport,
VkDescriptorSetVariableDescriptorCountLayoutSupportEXT* pVarDescSetCountSupport);
MVKPhysicalDevice* _physicalDevice;
MVKCommandResourceFactory* _commandResourceFactory;

View File

@ -129,6 +129,30 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
varPtrFeatures->variablePointers = true;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
auto* pDescIdxFeatures = (VkPhysicalDeviceDescriptorIndexingFeaturesEXT*)next;
pDescIdxFeatures->shaderInputAttachmentArrayDynamicIndexing = false;
pDescIdxFeatures->shaderUniformTexelBufferArrayDynamicIndexing = false;
pDescIdxFeatures->shaderStorageTexelBufferArrayDynamicIndexing = false;
pDescIdxFeatures->shaderUniformBufferArrayNonUniformIndexing = false;
pDescIdxFeatures->shaderSampledImageArrayNonUniformIndexing = false;
pDescIdxFeatures->shaderStorageBufferArrayNonUniformIndexing = false;
pDescIdxFeatures->shaderStorageImageArrayNonUniformIndexing = false;
pDescIdxFeatures->shaderInputAttachmentArrayNonUniformIndexing = false;
pDescIdxFeatures->shaderUniformTexelBufferArrayNonUniformIndexing = false;
pDescIdxFeatures->shaderStorageTexelBufferArrayNonUniformIndexing = false;
pDescIdxFeatures->descriptorBindingUniformBufferUpdateAfterBind = false;
pDescIdxFeatures->descriptorBindingSampledImageUpdateAfterBind = false;
pDescIdxFeatures->descriptorBindingStorageImageUpdateAfterBind = false;
pDescIdxFeatures->descriptorBindingStorageBufferUpdateAfterBind = false;
pDescIdxFeatures->descriptorBindingUniformTexelBufferUpdateAfterBind = false;
pDescIdxFeatures->descriptorBindingStorageTexelBufferUpdateAfterBind = false;
pDescIdxFeatures->descriptorBindingUpdateUnusedWhilePending = false;
pDescIdxFeatures->descriptorBindingPartiallyBound = false;
pDescIdxFeatures->descriptorBindingVariableDescriptorCount = false;
pDescIdxFeatures->runtimeDescriptorArray = false;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
@ -305,6 +329,33 @@ void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2* properties) {
}
break;
#endif
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT: {
auto* pDescIdxProps = (VkPhysicalDeviceDescriptorIndexingPropertiesEXT*)next;
pDescIdxProps->maxUpdateAfterBindDescriptorsInAllPools = kMVKUndefinedLargeUInt32;
pDescIdxProps->shaderUniformBufferArrayNonUniformIndexingNative = false;
pDescIdxProps->shaderSampledImageArrayNonUniformIndexingNative = false;
pDescIdxProps->shaderStorageBufferArrayNonUniformIndexingNative = false;
pDescIdxProps->shaderStorageImageArrayNonUniformIndexingNative = false;
pDescIdxProps->shaderInputAttachmentArrayNonUniformIndexingNative = false;
pDescIdxProps->robustBufferAccessUpdateAfterBind = false;
pDescIdxProps->quadDivergentImplicitLod = false;
pDescIdxProps->maxPerStageDescriptorUpdateAfterBindSamplers = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxPerStageDescriptorUpdateAfterBindUniformBuffers = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxPerStageDescriptorUpdateAfterBindStorageBuffers = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxPerStageDescriptorUpdateAfterBindSampledImages = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxPerStageDescriptorUpdateAfterBindStorageImages = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxPerStageDescriptorUpdateAfterBindInputAttachments = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxPerStageUpdateAfterBindResources = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindSamplers = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindUniformBuffers = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindStorageBuffers = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindSampledImages = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindStorageImages = kMVKUndefinedLargeUInt32;
pDescIdxProps->maxDescriptorSetUpdateAfterBindInputAttachments = kMVKUndefinedLargeUInt32;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: {
auto* inlineUniformBlockProps = (VkPhysicalDeviceInlineUniformBlockPropertiesEXT*)next;
inlineUniformBlockProps->maxInlineUniformBlockSize = _metalFeatures.dynamicMTLBufferSize;
@ -2490,6 +2541,120 @@ void MVKDevice::getDescriptorSetLayoutSupport(const VkDescriptorSetLayoutCreateI
descriptorCount += pCreateInfo->pBindings[i].descriptorCount;
}
pSupport->supported = (descriptorCount < ((_physicalDevice->_metalFeatures.maxPerStageBufferCount + _physicalDevice->_metalFeatures.maxPerStageTextureCount + _physicalDevice->_metalFeatures.maxPerStageSamplerCount) * 2));
// Check whether the layout has a variable-count descriptor, and if so, whether we can support it.
for (auto* next = (VkBaseOutStructure*)pSupport->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT: {
auto* pVarDescSetCountSupport = (VkDescriptorSetVariableDescriptorCountLayoutSupportEXT*)next;
getDescriptorVariableDescriptorCountLayoutSupport(pCreateInfo, pSupport, pVarDescSetCountSupport);
break;
}
default:
break;
}
}
}
// Check whether the layout has a variable-count descriptor, and if so, whether we can support it.
void MVKDevice::getDescriptorVariableDescriptorCountLayoutSupport(const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
VkDescriptorSetLayoutSupport* pSupport,
VkDescriptorSetVariableDescriptorCountLayoutSupportEXT* pVarDescSetCountSupport) {
// Assume we don't need this, then set appropriately if we do.
pVarDescSetCountSupport->maxVariableDescriptorCount = 0;
// Look for a variable length descriptor and remember its index.
int32_t varBindingIdx = -1;
for (const auto* next = (VkBaseInStructure*)pCreateInfo->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT: {
auto* pDescSetLayoutBindingFlags = (VkDescriptorSetLayoutBindingFlagsCreateInfoEXT*)next;
for (uint32_t bindIdx = 0; bindIdx < pDescSetLayoutBindingFlags->bindingCount; bindIdx++) {
if (mvkIsAnyFlagEnabled(pDescSetLayoutBindingFlags->pBindingFlags[bindIdx], VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)) {
varBindingIdx = bindIdx;
break;
}
}
break;
}
default:
break;
}
}
// If no variable length descriptor is found, we can skip the rest.
if (varBindingIdx < 0) { return; }
// Device does not support variable descriptor counts but it has been requested.
if ( !_enabledDescriptorIndexingFeatures.descriptorBindingVariableDescriptorCount ) {
pSupport->supported = false;
return;
}
uint32_t mtlBuffCnt = 0;
uint32_t mtlTexCnt = 0;
uint32_t mtlSampCnt = 0;
uint32_t requestedCount = 0;
uint32_t maxVarDescCount = 0;
// Determine the number of descriptors available for use by the variable descriptor by
// accumulating the number of resources accumulated by other descriptors and subtracting
// that from the device's per-stage max counts. This is not perfect because it does not
// take into consideration other descriptor sets in the pipeline layout, but we can't
// anticipate that here. The variable descriptor must have the highest binding number,
// but it may not be the last descriptor in the array. The handling here accommodates that.
for (uint32_t bindIdx = 0; bindIdx < pCreateInfo->bindingCount; bindIdx++) {
auto* pBind = &pCreateInfo->pBindings[bindIdx];
if (bindIdx == varBindingIdx) {
requestedCount = std::max(pBind->descriptorCount, 1u);
} else {
switch (pBind->descriptorType) {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
mtlBuffCnt += pBind->descriptorCount;
maxVarDescCount = _pMetalFeatures->maxPerStageBufferCount - mtlBuffCnt;
break;
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
maxVarDescCount = (uint32_t)min<VkDeviceSize>(_pMetalFeatures->maxMTLBufferSize, numeric_limits<uint32_t>::max());
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
mtlTexCnt += pBind->descriptorCount;
maxVarDescCount = _pMetalFeatures->maxPerStageTextureCount - mtlTexCnt;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
mtlTexCnt += pBind->descriptorCount;
mtlBuffCnt += pBind->descriptorCount;
maxVarDescCount = min(_pMetalFeatures->maxPerStageTextureCount - mtlTexCnt,
_pMetalFeatures->maxPerStageBufferCount - mtlBuffCnt);
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
mtlSampCnt += pBind->descriptorCount;
maxVarDescCount = _pMetalFeatures->maxPerStageSamplerCount - mtlSampCnt;
break;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
mtlTexCnt += pBind->descriptorCount;
mtlSampCnt += pBind->descriptorCount;
maxVarDescCount = min(_pMetalFeatures->maxPerStageTextureCount - mtlTexCnt,
_pMetalFeatures->maxPerStageSamplerCount - mtlSampCnt);
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: // excluded by Vulkan
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: // excluded by Vulkan
default:
break;
}
}
}
// If there is enough room for the requested size, indicate the amount available,
// otherwise indicate that the requested size cannot be supported.
if (requestedCount < maxVarDescCount) {
pVarDescSetCountSupport->maxVariableDescriptorCount = maxVarDescCount;
} else {
pSupport->supported = false;
}
}
VkResult MVKDevice::getDeviceGroupPresentCapabilities(VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities) {
@ -3125,6 +3290,7 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
_enabledF16I8Features(),
_enabledUBOLayoutFeatures(),
_enabledVarPtrFeatures(),
_enabledDescriptorIndexingFeatures(),
_enabledInterlockFeatures(),
_enabledHostQryResetFeatures(),
_enabledSamplerYcbcrConversionFeatures(),
@ -3241,7 +3407,6 @@ void MVKDevice::initPhysicalDevice(MVKPhysicalDevice* physicalDevice, const VkDe
_pProperties = &_physicalDevice->_properties;
_pMemoryProperties = &_physicalDevice->_memoryProperties;
// Indicates whether semaphores should use a MTLFence if available.
// Set by the MVK_ALLOW_METAL_FENCES environment variable if MTLFences are available.
// This should be a temporary fix after some repair to semaphore handling.
@ -3274,6 +3439,7 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
mvkClear(&_enabledF16I8Features);
mvkClear(&_enabledUBOLayoutFeatures);
mvkClear(&_enabledVarPtrFeatures);
mvkClear(&_enabledDescriptorIndexingFeatures);
mvkClear(&_enabledInterlockFeatures);
mvkClear(&_enabledHostQryResetFeatures);
mvkClear(&_enabledSamplerYcbcrConversionFeatures);
@ -3316,9 +3482,13 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
pdInterlockFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT;
pdInterlockFeatures.pNext = &pdHostQryResetFeatures;
VkPhysicalDeviceDescriptorIndexingFeaturesEXT pdDescIdxFeatures;
pdDescIdxFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
pdDescIdxFeatures.pNext = &pdInterlockFeatures;
VkPhysicalDeviceVariablePointerFeatures pdVarPtrFeatures;
pdVarPtrFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
pdVarPtrFeatures.pNext = &pdInterlockFeatures;
pdVarPtrFeatures.pNext = &pdDescIdxFeatures;
VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR pdUBOLayoutFeatures;
pdUBOLayoutFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR;
@ -3393,6 +3563,13 @@ void MVKDevice::enableFeatures(const VkDeviceCreateInfo* pCreateInfo) {
&pdVarPtrFeatures.variablePointersStorageBuffer, 2);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
auto* requestedFeatures = (VkPhysicalDeviceDescriptorIndexingFeaturesEXT*)next;
enableFeatures(&_enabledDescriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing,
&requestedFeatures->shaderInputAttachmentArrayDynamicIndexing,
&pdDescIdxFeatures.shaderInputAttachmentArrayDynamicIndexing, 20);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
auto* requestedFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
enableFeatures(&_enabledInterlockFeatures.fragmentShaderSampleInterlock,

View File

@ -80,6 +80,7 @@ MVK_EXTENSION(KHR_variable_pointers, KHR_VARIABLE_POINTERS, DEVICE)
MVK_EXTENSION(EXT_debug_marker, EXT_DEBUG_MARKER, DEVICE)
MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT, INSTANCE)
MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS, INSTANCE)
MVK_EXTENSION(EXT_descriptor_indexing, EXT_DESCRIPTOR_INDEXING, DEVICE)
MVK_EXTENSION(EXT_fragment_shader_interlock, EXT_FRAGMENT_SHADER_INTERLOCK, DEVICE)
MVK_EXTENSION(EXT_hdr_metadata, EXT_HDR_METADATA, DEVICE)
MVK_EXTENSION(EXT_host_query_reset, EXT_HOST_QUERY_RESET, DEVICE)

View File

@ -1172,9 +1172,7 @@ MVK_PUBLIC_SYMBOL VkResult vkAllocateDescriptorSets(
MVKTraceVulkanCallStart();
MVKDescriptorPool* mvkDP = (MVKDescriptorPool*)pAllocateInfo->descriptorPool;
VkResult rslt = mvkDP->allocateDescriptorSets(pAllocateInfo->descriptorSetCount,
pAllocateInfo->pSetLayouts,
pDescriptorSets);
VkResult rslt = mvkDP->allocateDescriptorSets(pAllocateInfo, pDescriptorSets);
MVKTraceVulkanCallEnd();
return rslt;
}