Merge pull request #1312 from billhollings/optimize-descriptor-sizes
MVKDescriptor subclasses: Reduce redundant and unused content.
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
index eb9637c..c2466a7 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
@@ -222,7 +222,6 @@
MVKSmallVector<VkBufferImageCopy, N> _bufferImageCopyRegions;
MVKBuffer* _buffer;
MVKImage* _image;
- VkImageLayout _imageLayout;
bool _toImage = false;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
index 5bee3c0..df50a7d 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
@@ -876,7 +876,6 @@
bool toImage) {
_buffer = (MVKBuffer*)buffer;
_image = (MVKImage*)image;
- _imageLayout = imageLayout;
_toImage = toImage;
// Add buffer regions
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h
index 23c599a..6aa2137 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.h
@@ -153,7 +153,8 @@
/** Encodes this descriptor (based on its layout binding index) on the the command encoder. */
virtual void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
@@ -164,7 +165,8 @@
* on the descriptor type, and is extracted from pData at the location given by index * stride.
* MVKInlineUniformBlockDescriptor uses the index as byte offset to write to.
*/
- virtual void write(MVKDescriptorSet* mvkDescSet,
+ virtual void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t index,
size_t stride,
const void* pData) = 0;
@@ -180,16 +182,14 @@
* at which to start writing.
* MVKInlineUniformBlockDescriptor uses the index as byte offset to read from.
*/
- virtual void read(MVKDescriptorSet* mvkDescSet,
+ virtual void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t index,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) = 0;
- /** Sets the binding layout. */
- virtual void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) {}
-
/** Resets any internal content. */
virtual void reset() {}
@@ -206,18 +206,21 @@
public:
void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) override;
- void write(MVKDescriptorSet* mvkDescSet,
+ void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
- void read(MVKDescriptorSet* mvkDescSet,
+ void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
@@ -281,33 +284,33 @@
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT; }
void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) override;
- void write(MVKDescriptorSet* mvkDescSet,
+ void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstOffset, // For inline buffers we are using this parameter as dst offset not as src descIdx
size_t stride,
const void* pData) override;
- void read(MVKDescriptorSet* mvkDescSet,
+ void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcOffset, // For inline buffers we are using this parameter as src offset not as dst descIdx
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
- void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) override;
-
void reset() override;
~MVKInlineUniformBlockDescriptor() { reset(); }
protected:
uint8_t* _buffer = nullptr;
- uint32_t _length;
};
@@ -319,18 +322,21 @@
public:
void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) override;
- void write(MVKDescriptorSet* mvkDescSet,
+ void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
- void read(MVKDescriptorSet* mvkDescSet,
+ void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
@@ -343,7 +349,6 @@
protected:
MVKImageView* _mvkImageView = nullptr;
- VkImageLayout _imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
};
@@ -388,32 +393,32 @@
protected:
void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex);
- void write(MVKDescriptorSet* mvkDescSet,
+ void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData);
- void read(MVKDescriptorSet* mvkDescSet,
+ void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock);
- void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index);
-
void reset();
~MVKSamplerDescriptorMixin() { reset(); }
MVKSampler* _mvkSampler = nullptr;
- bool _hasDynamicSampler = true;
};
@@ -427,26 +432,27 @@
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_SAMPLER; }
void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) override;
- void write(MVKDescriptorSet* mvkDescSet,
+ void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
- void read(MVKDescriptorSet* mvkDescSet,
+ void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
- void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) override;
-
void reset() override;
~MVKSamplerDescriptor() { reset(); }
@@ -464,26 +470,27 @@
VkDescriptorType getDescriptorType() override { return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; }
void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) override;
- void write(MVKDescriptorSet* mvkDescSet,
+ void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
- void read(MVKDescriptorSet* mvkDescSet,
+ void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* inlineUniformBlock) override;
- void setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) override;
-
void reset() override;
~MVKCombinedImageSamplerDescriptor() { reset(); }
@@ -499,18 +506,21 @@
public:
void bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) override;
- void write(MVKDescriptorSet* mvkDescSet,
+ void write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) override;
- void read(MVKDescriptorSet* mvkDescSet,
+ void read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm
index 43c1195..48ce529 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptor.mm
@@ -106,7 +106,7 @@
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
MVKDescriptor* mvkDesc = descSet->getDescriptor(getBinding(), descIdx);
if (mvkDesc->getDescriptorType() == descType) {
- mvkDesc->bind(cmdEncoder, descIdx, _applyToStage, mtlIdxs, dynamicOffsets, dynamicOffsetIndex);
+ mvkDesc->bind(cmdEncoder, this, descIdx, _applyToStage, mtlIdxs, dynamicOffsets, dynamicOffsetIndex);
}
}
}
@@ -509,7 +509,8 @@
// A null cmdEncoder can be passed to perform a validation pass
void MVKBufferDescriptor::bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
@@ -533,7 +534,7 @@
}
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
if (stages[i]) {
- bb.index = mtlIndexes.stages[i].bufferIndex + descriptorIndex;
+ bb.index = mtlIndexes.stages[i].bufferIndex + elementIndex;
if (i == kMVKShaderStageCompute) {
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindBuffer(bb); }
} else {
@@ -543,7 +544,8 @@
}
}
-void MVKBufferDescriptor::write(MVKDescriptorSet* mvkDescSet,
+void MVKBufferDescriptor::write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) {
@@ -558,7 +560,8 @@
if (oldBuff) { oldBuff->release(); }
}
-void MVKBufferDescriptor::read(MVKDescriptorSet* mvkDescSet,
+void MVKBufferDescriptor::read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
@@ -584,14 +587,15 @@
// A null cmdEncoder can be passed to perform a validation pass
void MVKInlineUniformBlockDescriptor::bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) {
MVKMTLBufferBinding bb;
bb.mtlBytes = _buffer;
- bb.size = _length;
+ bb.size = mvkDSLBind->_info.descriptorCount;
bb.isInline = true;
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
if (stages[i]) {
@@ -605,36 +609,39 @@
}
}
-void MVKInlineUniformBlockDescriptor::write(MVKDescriptorSet* mvkDescSet,
- uint32_t dstOffset,
- size_t stride,
- const void* pData) {
+void MVKInlineUniformBlockDescriptor::write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
+ uint32_t dstOffset,
+ size_t stride,
+ const void* pData) {
+ // Ensure there is a destination to write to
+ uint32_t buffSize = mvkDSLBind->_info.descriptorCount;
+ if ( !_buffer ) { _buffer = (uint8_t*)malloc(buffSize); }
+
const auto& pInlineUniformBlock = *(VkWriteDescriptorSetInlineUniformBlockEXT*)pData;
- if (pInlineUniformBlock.pData && _buffer) {
- memcpy(_buffer + dstOffset, pInlineUniformBlock.pData, pInlineUniformBlock.dataSize);
+ if (_buffer && pInlineUniformBlock.pData && dstOffset < buffSize) {
+ uint32_t dataLen = std::min(pInlineUniformBlock.dataSize, buffSize - dstOffset);
+ memcpy(_buffer + dstOffset, pInlineUniformBlock.pData, dataLen);
}
}
-void MVKInlineUniformBlockDescriptor::read(MVKDescriptorSet* mvkDescSet,
- uint32_t srcOffset,
- VkDescriptorImageInfo* pImageInfo,
- VkDescriptorBufferInfo* pBufferInfo,
- VkBufferView* pTexelBufferView,
- VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
- if (_buffer && pInlineUniformBlock->pData) {
- memcpy((void*)pInlineUniformBlock->pData, _buffer + srcOffset, pInlineUniformBlock->dataSize);
+void MVKInlineUniformBlockDescriptor::read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
+ uint32_t srcOffset,
+ VkDescriptorImageInfo* pImageInfo,
+ VkDescriptorBufferInfo* pBufferInfo,
+ VkBufferView* pTexelBufferView,
+ VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
+ uint32_t buffSize = mvkDSLBind->_info.descriptorCount;
+ if (_buffer && pInlineUniformBlock->pData && srcOffset < buffSize) {
+ uint32_t dataLen = std::min(pInlineUniformBlock->dataSize, buffSize - srcOffset);
+ memcpy((void*)pInlineUniformBlock->pData, _buffer + srcOffset, dataLen);
}
}
-void MVKInlineUniformBlockDescriptor::setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) {
- _length = dslBinding->_info.descriptorCount;
- _buffer = (uint8_t*)malloc(_length);
-}
-
void MVKInlineUniformBlockDescriptor::reset() {
free(_buffer);
_buffer = nullptr;
- _length = 0;
MVKDescriptor::reset();
}
@@ -644,7 +651,8 @@
// A null cmdEncoder can be passed to perform a validation pass
void MVKImageDescriptor::bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
@@ -671,14 +679,14 @@
}
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
if (stages[i]) {
- tb.index = mtlIndexes.stages[i].textureIndex + descriptorIndex + planeIndex;
+ tb.index = mtlIndexes.stages[i].textureIndex + elementIndex + planeIndex;
if (i == kMVKShaderStageCompute) {
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindTexture(tb); }
} else {
if (cmdEncoder) { cmdEncoder->_graphicsResourcesState.bindTexture(MVKShaderStage(i), tb); }
}
if (descType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
- bb.index = mtlIndexes.stages[i].bufferIndex + descriptorIndex + planeIndex;
+ bb.index = mtlIndexes.stages[i].bufferIndex + elementIndex + planeIndex;
if (i == kMVKShaderStageCompute) {
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindBuffer(bb); }
} else {
@@ -690,7 +698,8 @@
}
}
-void MVKImageDescriptor::write(MVKDescriptorSet* mvkDescSet,
+void MVKImageDescriptor::write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) {
@@ -698,13 +707,13 @@
const auto* pImgInfo = &get<VkDescriptorImageInfo>(pData, stride, srcIndex);
_mvkImageView = (MVKImageView*)pImgInfo->imageView;
- _imageLayout = pImgInfo->imageLayout;
if (_mvkImageView) { _mvkImageView->retain(); }
if (oldImgView) { oldImgView->release(); }
}
-void MVKImageDescriptor::read(MVKDescriptorSet* mvkDescSet,
+void MVKImageDescriptor::read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
@@ -712,13 +721,12 @@
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
auto& imgInfo = pImageInfo[dstIndex];
imgInfo.imageView = (VkImageView)_mvkImageView;
- imgInfo.imageLayout = _imageLayout;
+ imgInfo.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
}
void MVKImageDescriptor::reset() {
if (_mvkImageView) { _mvkImageView->release(); }
_mvkImageView = nullptr;
- _imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
MVKDescriptor::reset();
}
@@ -730,18 +738,23 @@
// Metal validation requires each sampler in an array of samplers to be populated,
// even if not used, so populate a default if one hasn't been set.
void MVKSamplerDescriptorMixin::bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) {
+
+ MVKSampler* imutSamp = mvkDSLBind->getImmutableSampler(elementIndex);
+ MVKSampler* mvkSamp = imutSamp ? imutSamp : _mvkSampler;
+
MVKMTLSamplerStateBinding sb;
- sb.mtlSamplerState = (_mvkSampler
- ? _mvkSampler->getMTLSamplerState()
+ sb.mtlSamplerState = (mvkSamp
+ ? mvkSamp->getMTLSamplerState()
: cmdEncoder->getDevice()->getDefaultMTLSamplerState());
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
if (stages[i]) {
- sb.index = mtlIndexes.stages[i].samplerIndex + descriptorIndex;
+ sb.index = mtlIndexes.stages[i].samplerIndex + elementIndex;
if (i == kMVKShaderStageCompute) {
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindSamplerState(sb); }
} else {
@@ -751,50 +764,37 @@
}
}
-void MVKSamplerDescriptorMixin::write(MVKDescriptorSet* mvkDescSet,
+void MVKSamplerDescriptorMixin::write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) {
- if (_hasDynamicSampler) {
- auto* oldSamp = _mvkSampler;
+ auto* oldSamp = _mvkSampler;
- const auto* pImgInfo = &get<VkDescriptorImageInfo>(pData, stride, srcIndex);
- _mvkSampler = (MVKSampler*)pImgInfo->sampler;
- if (_mvkSampler && _mvkSampler->getRequiresConstExprSampler()) {
- _mvkSampler->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkUpdateDescriptorSets(): Tried to push an immutable sampler.");
- }
-
- if (_mvkSampler) { _mvkSampler->retain(); }
- if (oldSamp) { oldSamp->release(); }
+ const auto* pImgInfo = &get<VkDescriptorImageInfo>(pData, stride, srcIndex);
+ _mvkSampler = (MVKSampler*)pImgInfo->sampler;
+ if (_mvkSampler && _mvkSampler->getRequiresConstExprSampler()) {
+ _mvkSampler->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkUpdateDescriptorSets(): Tried to push an immutable sampler.");
}
+
+ if (_mvkSampler) { _mvkSampler->retain(); }
+ if (oldSamp) { oldSamp->release(); }
}
-void MVKSamplerDescriptorMixin::read(MVKDescriptorSet* mvkDescSet,
+void MVKSamplerDescriptorMixin::read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
auto& imgInfo = pImageInfo[dstIndex];
- imgInfo.sampler = _hasDynamicSampler ? (VkSampler)_mvkSampler : nullptr;
-}
-
-// If the descriptor set layout binding contains immutable samplers, use them
-// Otherwise the sampler will be populated dynamically at a later time.
-void MVKSamplerDescriptorMixin::setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) {
- auto* oldSamp = _mvkSampler;
-
- _mvkSampler = dslBinding->getImmutableSampler(index);
- _hasDynamicSampler = !_mvkSampler;
-
- if (_mvkSampler) { _mvkSampler->retain(); }
- if (oldSamp) { oldSamp->release(); }
+ imgInfo.sampler = (VkSampler)_mvkSampler;
}
void MVKSamplerDescriptorMixin::reset() {
if (_mvkSampler) { _mvkSampler->release(); }
_mvkSampler = nullptr;
- _hasDynamicSampler = true;
}
@@ -803,33 +803,31 @@
// A null cmdEncoder can be passed to perform a validation pass
void MVKSamplerDescriptor::bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) {
- MVKSamplerDescriptorMixin::bind(cmdEncoder, descriptorIndex, stages, mtlIndexes, dynamicOffsets, dynamicOffsetIndex);
+ MVKSamplerDescriptorMixin::bind(cmdEncoder, mvkDSLBind, elementIndex, stages, mtlIndexes, dynamicOffsets, dynamicOffsetIndex);
}
-void MVKSamplerDescriptor::write(MVKDescriptorSet* mvkDescSet,
+void MVKSamplerDescriptor::write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) {
- MVKSamplerDescriptorMixin::write(mvkDescSet, srcIndex, stride, pData);
+ MVKSamplerDescriptorMixin::write(mvkDSLBind, mvkDescSet, srcIndex, stride, pData);
}
-void MVKSamplerDescriptor::read(MVKDescriptorSet* mvkDescSet,
+void MVKSamplerDescriptor::read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
- MVKSamplerDescriptorMixin::read(mvkDescSet, dstIndex, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
-}
-
-void MVKSamplerDescriptor::setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) {
- MVKDescriptor::setLayout(dslBinding, index);
- MVKSamplerDescriptorMixin::setLayout(dslBinding, index);
+ MVKSamplerDescriptorMixin::read(mvkDSLBind, mvkDescSet, dstIndex, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
}
void MVKSamplerDescriptor::reset() {
@@ -843,36 +841,34 @@
// A null cmdEncoder can be passed to perform a validation pass
void MVKCombinedImageSamplerDescriptor::bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
uint32_t& dynamicOffsetIndex) {
- MVKImageDescriptor::bind(cmdEncoder, descriptorIndex, stages, mtlIndexes, dynamicOffsets, dynamicOffsetIndex);
- MVKSamplerDescriptorMixin::bind(cmdEncoder, descriptorIndex, stages, mtlIndexes, dynamicOffsets, dynamicOffsetIndex);
+ MVKImageDescriptor::bind(cmdEncoder, mvkDSLBind, elementIndex, stages, mtlIndexes, dynamicOffsets, dynamicOffsetIndex);
+ MVKSamplerDescriptorMixin::bind(cmdEncoder, mvkDSLBind, elementIndex, stages, mtlIndexes, dynamicOffsets, dynamicOffsetIndex);
}
-void MVKCombinedImageSamplerDescriptor::write(MVKDescriptorSet* mvkDescSet,
+void MVKCombinedImageSamplerDescriptor::write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) {
- MVKImageDescriptor::write(mvkDescSet, srcIndex, stride, pData);
- MVKSamplerDescriptorMixin::write(mvkDescSet, srcIndex, stride, pData);
+ MVKImageDescriptor::write(mvkDSLBind, mvkDescSet, srcIndex, stride, pData);
+ MVKSamplerDescriptorMixin::write(mvkDSLBind, mvkDescSet, srcIndex, stride, pData);
}
-void MVKCombinedImageSamplerDescriptor::read(MVKDescriptorSet* mvkDescSet,
+void MVKCombinedImageSamplerDescriptor::read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
- MVKImageDescriptor::read(mvkDescSet, dstIndex, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
- MVKSamplerDescriptorMixin::read(mvkDescSet, dstIndex, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
-}
-
-void MVKCombinedImageSamplerDescriptor::setLayout(MVKDescriptorSetLayoutBinding* dslBinding, uint32_t index) {
- MVKImageDescriptor::setLayout(dslBinding, index);
- MVKSamplerDescriptorMixin::setLayout(dslBinding, index);
+ MVKImageDescriptor::read(mvkDSLBind, mvkDescSet, dstIndex, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
+ MVKSamplerDescriptorMixin::read(mvkDSLBind, mvkDescSet, dstIndex, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
}
void MVKCombinedImageSamplerDescriptor::reset() {
@@ -886,7 +882,8 @@
// A null cmdEncoder can be passed to perform a validation pass
void MVKTexelBufferDescriptor::bind(MVKCommandEncoder* cmdEncoder,
- uint32_t descriptorIndex,
+ MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ uint32_t elementIndex,
bool stages[],
MVKShaderResourceBinding& mtlIndexes,
MVKArrayRef<uint32_t> dynamicOffsets,
@@ -905,14 +902,14 @@
}
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
if (stages[i]) {
- tb.index = mtlIndexes.stages[i].textureIndex + descriptorIndex;
+ tb.index = mtlIndexes.stages[i].textureIndex + elementIndex;
if (i == kMVKShaderStageCompute) {
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindTexture(tb); }
} else {
if (cmdEncoder) { cmdEncoder->_graphicsResourcesState.bindTexture(MVKShaderStage(i), tb); }
}
if (descType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
- bb.index = mtlIndexes.stages[i].bufferIndex + descriptorIndex;
+ bb.index = mtlIndexes.stages[i].bufferIndex + elementIndex;
if (i == kMVKShaderStageCompute) {
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindBuffer(bb); }
} else {
@@ -923,7 +920,8 @@
}
}
-void MVKTexelBufferDescriptor::write(MVKDescriptorSet* mvkDescSet,
+void MVKTexelBufferDescriptor::write(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t srcIndex,
size_t stride,
const void* pData) {
@@ -936,7 +934,8 @@
if (oldBuffView) { oldBuffView->release(); }
}
-void MVKTexelBufferDescriptor::read(MVKDescriptorSet* mvkDescSet,
+void MVKTexelBufferDescriptor::read(MVKDescriptorSetLayoutBinding* mvkDSLBind,
+ MVKDescriptorSet* mvkDescSet,
uint32_t dstIndex,
VkDescriptorImageInfo* pImageInfo,
VkDescriptorBufferInfo* pBufferInfo,
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm
index 5630f4e..16a79ef 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm
@@ -235,12 +235,13 @@
size_t stride,
const void* pData) {
- VkDescriptorType descType = getDescriptorType(pDescriptorAction->dstBinding);
+ MVKDescriptorSetLayoutBinding* mvkDSLBind = _layout->getBinding(pDescriptorAction->dstBinding);
+ VkDescriptorType descType = mvkDSLBind->getDescriptorType();
if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
// For inline buffers dstArrayElement is a byte offset
MVKDescriptor* mvkDesc = getDescriptor(pDescriptorAction->dstBinding);
if (mvkDesc->getDescriptorType() == descType) {
- mvkDesc->write(this, pDescriptorAction->dstArrayElement, stride, pData);
+ mvkDesc->write(mvkDSLBind, this, pDescriptorAction->dstArrayElement, stride, pData);
}
} else {
uint32_t dstStartIdx = _layout->getDescriptorIndex(pDescriptorAction->dstBinding, pDescriptorAction->dstArrayElement);
@@ -248,7 +249,7 @@
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
MVKDescriptor* mvkDesc = _descriptors[dstStartIdx + descIdx];
if (mvkDesc->getDescriptorType() == descType) {
- mvkDesc->write(this, descIdx, stride, pData);
+ mvkDesc->write(mvkDSLBind, this, descIdx, stride, pData);
}
}
}
@@ -260,20 +261,21 @@
VkBufferView* pTexelBufferView,
VkWriteDescriptorSetInlineUniformBlockEXT* pInlineUniformBlock) {
- VkDescriptorType descType = getDescriptorType(pDescriptorCopy->srcBinding);
+ MVKDescriptorSetLayoutBinding* mvkDSLBind = _layout->getBinding(pDescriptorCopy->srcBinding);
+ VkDescriptorType descType = mvkDSLBind->getDescriptorType();
uint32_t descCnt = pDescriptorCopy->descriptorCount;
if (descType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
// For inline buffers srcArrayElement is a byte offset
MVKDescriptor* mvkDesc = getDescriptor(pDescriptorCopy->srcBinding);
if (mvkDesc->getDescriptorType() == descType) {
- mvkDesc->read(this, pDescriptorCopy->srcArrayElement, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
+ mvkDesc->read(mvkDSLBind, this, pDescriptorCopy->srcArrayElement, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
}
} else {
uint32_t srcStartIdx = _layout->getDescriptorIndex(pDescriptorCopy->srcBinding, pDescriptorCopy->srcArrayElement);
for (uint32_t descIdx = 0; descIdx < descCnt; descIdx++) {
MVKDescriptor* mvkDesc = _descriptors[srcStartIdx + descIdx];
if (mvkDesc->getDescriptorType() == descType) {
- mvkDesc->read(this, descIdx, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
+ mvkDesc->read(mvkDSLBind, this, descIdx, pImageInfo, pBufferInfo, pTexelBufferView, pInlineUniformBlock);
}
}
}
@@ -296,8 +298,6 @@
MVKDescriptor* mvkDesc = nullptr;
setConfigurationResult(_pool->allocateDescriptor(mvkDSLBind->getDescriptorType(), &mvkDesc));
if ( !wasConfigurationSuccessful() ) { break; }
-
- mvkDesc->setLayout(mvkDSLBind, descIdx);
_descriptors.push_back(mvkDesc);
}
if ( !wasConfigurationSuccessful() ) { break; }