Fixes 4 bugs in VK_EXT_inline_uniform_block:
descriptorCount measures bytes, array indices are offsets into the buffer, missing isInline flag in bind, missing struct VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT.
This commit is contained in:
parent
06747095c5
commit
4a09c7aa20
@ -71,7 +71,7 @@ public:
|
||||
inline uint32_t getBinding() { return _info.binding; }
|
||||
|
||||
/** Returns the number of descriptors in this layout. */
|
||||
inline uint32_t getDescriptorCount() { return _info.descriptorCount; }
|
||||
inline uint32_t getDescriptorCount() { return (_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) ? 1 : _info.descriptorCount; }
|
||||
|
||||
/** Returns the descriptor type of this layout. */
|
||||
inline VkDescriptorType getDescriptorType() { return _info.descriptorType; }
|
||||
@ -284,17 +284,19 @@ public:
|
||||
|
||||
void write(MVKDescriptorSet* mvkDescSet,
|
||||
VkDescriptorType descriptorType,
|
||||
uint32_t srcIndex,
|
||||
uint32_t dstIndex,
|
||||
size_t stride,
|
||||
const void* pData) override;
|
||||
|
||||
void read(MVKDescriptorSet* mvkDescSet,
|
||||
VkDescriptorType descriptorType,
|
||||
uint32_t dstIndex,
|
||||
uint32_t srcIndex,
|
||||
VkDescriptorImageInfo* pImageInfo,
|
||||
VkDescriptorBufferInfo* pBufferInfo,
|
||||
VkBufferView* pTexelBufferView,
|
||||
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
|
||||
|
||||
void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) override;
|
||||
|
||||
void reset() override;
|
||||
|
||||
@ -302,7 +304,6 @@ public:
|
||||
|
||||
protected:
|
||||
id<MTLBuffer> _mtlBuffer = nil;
|
||||
uint32_t _dataSize = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -89,13 +89,18 @@ uint32_t MVKDescriptorSetLayoutBinding::bind(MVKCommandEncoder* cmdEncoder,
|
||||
// Establish the resource indices to use, by combining the offsets of the DSL and this DSL binding.
|
||||
MVKShaderResourceBinding mtlIdxs = _mtlResourceIndexOffsets + dslMTLRezIdxOffsets;
|
||||
|
||||
uint32_t descCnt = _info.descriptorCount;
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
MVKDescriptor* mvkDesc = descSet->getDescriptor(descStartIndex + descIdx);
|
||||
mvkDesc->bind(cmdEncoder, _info.descriptorType, descIdx, _applyToStage,
|
||||
mtlIdxs, dynamicOffsets, pDynamicOffsetIndex);
|
||||
if (_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
|
||||
MVKDescriptor* mvkDesc = descSet->getDescriptor(descStartIndex);
|
||||
mvkDesc->bind(cmdEncoder, _info.descriptorType, 0, _applyToStage, mtlIdxs, dynamicOffsets, pDynamicOffsetIndex);
|
||||
return 1;
|
||||
} else {
|
||||
uint32_t descCnt = _info.descriptorCount;
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
MVKDescriptor* mvkDesc = descSet->getDescriptor(descStartIndex + descIdx);
|
||||
mvkDesc->bind(cmdEncoder, _info.descriptorType, descIdx, _applyToStage, mtlIdxs, dynamicOffsets, pDynamicOffsetIndex);
|
||||
}
|
||||
return descCnt;
|
||||
}
|
||||
return descCnt;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -167,13 +172,13 @@ void MVKDescriptorSetLayoutBinding::push(MVKCommandEncoder* cmdEncoder,
|
||||
}
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
const auto& inlineUniformBlock = get<VkWriteDescriptorSetInlineUniformBlockEXT>(pData, stride, rezIdx - dstArrayElement);
|
||||
const auto& inlineUniformBlock = *(VkWriteDescriptorSetInlineUniformBlockEXT*)pData;
|
||||
bb.mtlBytes = inlineUniformBlock.pData;
|
||||
bb.size = inlineUniformBlock.dataSize;
|
||||
bb.isInline = true;
|
||||
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
|
||||
if (_applyToStage[i]) {
|
||||
bb.index = mtlIdxs.stages[i].bufferIndex + rezIdx;
|
||||
bb.index = mtlIdxs.stages[i].bufferIndex;
|
||||
if (i == kMVKShaderStageCompute) {
|
||||
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindBuffer(bb); }
|
||||
} else {
|
||||
@ -470,11 +475,15 @@ void MVKDescriptorSetLayoutBinding::initMetalResourceIndexOffsets(MVKShaderStage
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
|
||||
pBindingIndexes->bufferIndex = pDescSetCounts->bufferIndex;
|
||||
pDescSetCounts->bufferIndex += pBinding->descriptorCount;
|
||||
break;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
|
||||
pBindingIndexes->bufferIndex = pDescSetCounts->bufferIndex;
|
||||
pDescSetCounts->bufferIndex += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -605,18 +614,19 @@ void MVKInlineUniformBlockDescriptor::bind(MVKCommandEncoder* cmdEncoder,
|
||||
|
||||
switch (descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
bb.mtlBuffer = _mtlBuffer;
|
||||
bb.size = _dataSize;
|
||||
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
|
||||
if (stages[i]) {
|
||||
bb.index = mtlIndexes.stages[i].bufferIndex + descriptorIndex;
|
||||
if (i == kMVKShaderStageCompute) {
|
||||
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindBuffer(bb); }
|
||||
} else {
|
||||
if (cmdEncoder) { cmdEncoder->_graphicsResourcesState.bindBuffer(MVKShaderStage(i), bb); }
|
||||
}
|
||||
}
|
||||
}
|
||||
bb.mtlBytes = _mtlBuffer.contents;
|
||||
bb.size = (uint32_t)_mtlBuffer.length;
|
||||
bb.isInline = true;
|
||||
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
|
||||
if (stages[i]) {
|
||||
bb.index = mtlIndexes.stages[i].bufferIndex;
|
||||
if (i == kMVKShaderStageCompute) {
|
||||
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindBuffer(bb); }
|
||||
} else {
|
||||
if (cmdEncoder) { cmdEncoder->_graphicsResourcesState.bindBuffer(MVKShaderStage(i), bb); }
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -626,25 +636,18 @@ void MVKInlineUniformBlockDescriptor::bind(MVKCommandEncoder* cmdEncoder,
|
||||
}
|
||||
|
||||
void MVKInlineUniformBlockDescriptor::write(MVKDescriptorSet* mvkDescSet,
|
||||
VkDescriptorType descriptorType,
|
||||
uint32_t srcIndex,
|
||||
size_t stride,
|
||||
const void* pData) {
|
||||
VkDescriptorType descriptorType,
|
||||
uint32_t dstIndex,
|
||||
size_t stride,
|
||||
const void* pData) {
|
||||
switch (descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
const auto& srcInlineUniformBlock = get<VkWriteDescriptorSetInlineUniformBlockEXT>(pData, stride, srcIndex);
|
||||
_dataSize = srcInlineUniformBlock.dataSize;
|
||||
|
||||
[_mtlBuffer release];
|
||||
if (srcInlineUniformBlock.dataSize > 0) {
|
||||
MTLResourceOptions mtlBuffOpts = MTLResourceStorageModeShared | MTLResourceCPUCacheModeDefaultCache;
|
||||
_mtlBuffer = [mvkDescSet->getMTLDevice() newBufferWithBytes: srcInlineUniformBlock.pData
|
||||
length: srcInlineUniformBlock.dataSize
|
||||
options:mtlBuffOpts]; // retained
|
||||
} else {
|
||||
_mtlBuffer = nil;
|
||||
}
|
||||
|
||||
const auto& pInlineUniformBlock = *(VkWriteDescriptorSetInlineUniformBlockEXT*)pData;
|
||||
uint8_t* pDstData = (uint8_t*)_mtlBuffer.contents;
|
||||
uint8_t* pSrcData = (uint8_t*)pInlineUniformBlock.pData;
|
||||
if (pSrcData && pDstData) {
|
||||
memcpy(pDstData + dstIndex, pSrcData, pInlineUniformBlock.dataSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -654,23 +657,19 @@ void MVKInlineUniformBlockDescriptor::write(MVKDescriptorSet* mvkDescSet,
|
||||
}
|
||||
|
||||
void MVKInlineUniformBlockDescriptor::read(MVKDescriptorSet* mvkDescSet,
|
||||
VkDescriptorType descriptorType,
|
||||
uint32_t dstIndex,
|
||||
VkDescriptorImageInfo* pImageInfo,
|
||||
VkDescriptorBufferInfo* pBufferInfo,
|
||||
VkBufferView* pTexelBufferView,
|
||||
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
|
||||
VkDescriptorType descriptorType,
|
||||
uint32_t srcIndex,
|
||||
VkDescriptorImageInfo* pImageInfo,
|
||||
VkDescriptorBufferInfo* pBufferInfo,
|
||||
VkBufferView* pTexelBufferView,
|
||||
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
|
||||
switch (descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
|
||||
auto& dstInlineUniformBlock = pInlineUniformBlock[dstIndex];
|
||||
void* pDstData = const_cast<void*>(dstInlineUniformBlock.pData);
|
||||
void* pSrcData = _mtlBuffer.contents;
|
||||
uint8_t* pDstData = (uint8_t*)pInlineUniformBlock->pData;
|
||||
uint8_t* pSrcData = (uint8_t*)_mtlBuffer.contents;
|
||||
if (pSrcData && pDstData) {
|
||||
memcpy(pDstData, pSrcData, _dataSize);
|
||||
dstInlineUniformBlock.dataSize = _dataSize;
|
||||
} else {
|
||||
dstInlineUniformBlock.dataSize = 0;
|
||||
}
|
||||
memcpy(pDstData, pSrcData + srcIndex, pInlineUniformBlock->dataSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -679,10 +678,14 @@ void MVKInlineUniformBlockDescriptor::read(MVKDescriptorSet* mvkDescSet,
|
||||
}
|
||||
}
|
||||
|
||||
void MVKInlineUniformBlockDescriptor::setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) {
|
||||
_mtlBuffer = [dslBinding->getMTLDevice() newBufferWithLength: dslBinding->getDescriptorCount()
|
||||
options: MTLResourceStorageModeShared | MTLResourceCPUCacheModeDefaultCache]; // retained
|
||||
}
|
||||
|
||||
void MVKInlineUniformBlockDescriptor::reset() {
|
||||
[_mtlBuffer release];
|
||||
_mtlBuffer = nil;
|
||||
_dataSize = 0;
|
||||
MVKDescriptor::reset();
|
||||
}
|
||||
|
||||
|
@ -209,12 +209,17 @@ void MVKDescriptorSet::write(const DescriptorAction* pDescriptorAction,
|
||||
const void* pData) {
|
||||
|
||||
VkDescriptorType descType = getDescriptorType(pDescriptorAction->dstBinding);
|
||||
uint32_t dstStartIdx = _layout->getDescriptorIndex(pDescriptorAction->dstBinding,
|
||||
pDescriptorAction->dstArrayElement);
|
||||
uint32_t descCnt = pDescriptorAction->descriptorCount;
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
_descriptors[dstStartIdx + descIdx]->write(this, descType, descIdx, stride, pData);
|
||||
}
|
||||
if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
|
||||
uint32_t dstStartIdx = _layout->getDescriptorIndex(pDescriptorAction->dstBinding, 0);
|
||||
_descriptors[dstStartIdx]->write(this, descType, pDescriptorAction->dstArrayElement, stride, pData);
|
||||
} else {
|
||||
uint32_t dstStartIdx = _layout->getDescriptorIndex(pDescriptorAction->dstBinding,
|
||||
pDescriptorAction->dstArrayElement);
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
_descriptors[dstStartIdx + descIdx]->write(this, descType, descIdx, stride, pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create concrete implementations of the three variations of the write() function.
|
||||
@ -232,13 +237,18 @@ void MVKDescriptorSet::read(const VkCopyDescriptorSet* pDescriptorCopy,
|
||||
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
|
||||
|
||||
VkDescriptorType descType = getDescriptorType(pDescriptorCopy->srcBinding);
|
||||
uint32_t srcStartIdx = _layout->getDescriptorIndex(pDescriptorCopy->srcBinding,
|
||||
pDescriptorCopy->srcArrayElement);
|
||||
uint32_t descCnt = pDescriptorCopy->descriptorCount;
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
_descriptors[srcStartIdx + descIdx]->read(this, descType, descIdx, pImageInfo, pBufferInfo,
|
||||
pTexelBufferView, pInlineUniformBlock);
|
||||
}
|
||||
if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
|
||||
pInlineUniformBlock->dataSize = pDescriptorCopy->descriptorCount;
|
||||
uint32_t srcStartIdx = _layout->getDescriptorIndex(pDescriptorCopy->srcBinding, 0);
|
||||
_descriptors[srcStartIdx]->read(this, descType, pDescriptorCopy->srcArrayElement, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
|
||||
} else {
|
||||
uint32_t srcStartIdx = _layout->getDescriptorIndex(pDescriptorCopy->srcBinding,
|
||||
pDescriptorCopy->srcArrayElement);
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
_descriptors[srcStartIdx + descIdx]->read(this, descType, descIdx, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the descriptor pool fails to allocate a descriptor, record a configuration error
|
||||
@ -249,15 +259,23 @@ MVKDescriptorSet::MVKDescriptorSet(MVKDescriptorSetLayout* layout, MVKDescriptor
|
||||
uint32_t bindCnt = (uint32_t)layout->_bindings.size();
|
||||
for (uint32_t bindIdx = 0; bindIdx < bindCnt; bindIdx++) {
|
||||
MVKDescriptorSetLayoutBinding* mvkDSLBind = &layout->_bindings[bindIdx];
|
||||
uint32_t descCnt = mvkDSLBind->getDescriptorCount();
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
MVKDescriptor* mvkDesc = nullptr;
|
||||
setConfigurationResult(_pool->allocateDescriptor(mvkDSLBind->getDescriptorType(), &mvkDesc));
|
||||
if ( !wasConfigurationSuccessful() ) { break; }
|
||||
MVKDescriptor* mvkDesc = nullptr;
|
||||
if (mvkDSLBind->getDescriptorType() == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
|
||||
setConfigurationResult(_pool->allocateDescriptor(mvkDSLBind->getDescriptorType(), &mvkDesc));
|
||||
if ( !wasConfigurationSuccessful() ) { break; }
|
||||
|
||||
mvkDesc->setLayout(mvkDSLBind, descIdx);
|
||||
_descriptors.push_back(mvkDesc);
|
||||
}
|
||||
mvkDesc->setLayout(mvkDSLBind, 0);
|
||||
_descriptors.push_back(mvkDesc);
|
||||
} else {
|
||||
uint32_t descCnt = mvkDSLBind->getDescriptorCount();
|
||||
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
|
||||
setConfigurationResult(_pool->allocateDescriptor(mvkDSLBind->getDescriptorType(), &mvkDesc));
|
||||
if ( !wasConfigurationSuccessful() ) { break; }
|
||||
|
||||
mvkDesc->setLayout(mvkDSLBind, descIdx);
|
||||
_descriptors.push_back(mvkDesc);
|
||||
}
|
||||
}
|
||||
if ( !wasConfigurationSuccessful() ) { break; }
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +209,15 @@ void MVKPhysicalDevice::getProperties(VkPhysicalDeviceProperties2* properties) {
|
||||
portabilityProps->minVertexInputBindingStrideAlignment = 4;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: {
|
||||
auto* inlineUniformBlockProps = (VkPhysicalDeviceInlineUniformBlockPropertiesEXT*)next;
|
||||
inlineUniformBlockProps->maxInlineUniformBlockSize = _metalFeatures.dynamicMTLBufferSize;
|
||||
inlineUniformBlockProps->maxPerStageDescriptorInlineUniformBlocks = _properties.limits.maxPerStageDescriptorUniformBuffers;
|
||||
inlineUniformBlockProps->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = _properties.limits.maxPerStageDescriptorUniformBuffers;
|
||||
inlineUniformBlockProps->maxDescriptorSetInlineUniformBlocks = _properties.limits.maxDescriptorSetUniformBuffers;
|
||||
inlineUniformBlockProps->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = _properties.limits.maxDescriptorSetUniformBuffers;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user