Merge pull request #714 from billhollings/master
Fix crash in vkDestroyPipelineLayout()
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index c3fe0f6..fd3c8e8 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -24,10 +24,15 @@
- Revert to supporting host-coherent memory for linear images on macOS.
- Ensure Vulkan loader magic number is set every time before returning any dispatchable Vulkan handle.
- Fix crash when `VkDeviceCreateInfo` specifies queue families out of numerical order.
+- Fix crash in `vkDestroyPipelineLayout()`.
+- `vkCmdClearImage()` set error if attempt made to clear 1D image.
+- Remove error logging on `VK_TIMEOUT` of `VkSemaphore` and `VkFence`.
- Consolidate the various linkable objects into a `MVKLinkableMixin` template base class.
- Use `MVKVector` whenever possible in MoltenVK, especially within render loop.
- No longer prefer dedicated allocations for buffer memory, including buffer-backed images.
- Handle the `compositeAlpha` member of `VkSwapchainCreateInfoKHR`.
+- `VkPhysicalDevicePortabilitySubsetFeaturesEXTX::events` set to `true`.
+
MoltenVK 1.0.36
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
index 40c1fa1..103befb 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm
@@ -1055,6 +1055,9 @@
}
// Validate
+ if (_image->getImageType() == VK_IMAGE_TYPE_1D) {
+ setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClearImage(): 1D images cannot be cleared on this device."));
+ }
if ( !_image->getSupportsAllFormatFeatures(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ) {
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdClearImage(): Format %s cannot be cleared on this device.", mvkVkFormatName(_image->getVkFormat())));
}
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 2f73064..e900a61 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -128,7 +128,7 @@
auto* portabilityFeatures = (VkPhysicalDevicePortabilitySubsetFeaturesEXTX*)next;
portabilityFeatures->triangleFans = false;
portabilityFeatures->separateStencilMaskRef = true;
- portabilityFeatures->events = _metalFeatures.events;
+ portabilityFeatures->events = true;
portabilityFeatures->standardImageViews = _mvkInstance->getMoltenVKConfiguration()->fullImageViewSwizzle;
portabilityFeatures->samplerMipLodBias = false;
break;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
index 30d48c2..020af29 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
@@ -102,10 +102,12 @@
/** Constructs an instance for the specified device. */
MVKPipelineLayout(MVKDevice* device, const VkPipelineLayoutCreateInfo* pCreateInfo);
+ ~MVKPipelineLayout() override;
+
protected:
void propogateDebugName() override {}
- MVKVectorInline<MVKDescriptorSetLayout, 8> _descriptorSetLayouts;
+ MVKVectorInline<MVKDescriptorSetLayout*, 8> _descriptorSetLayouts;
MVKVectorInline<MVKShaderResourceBinding, 8> _dslMTLResourceIndexOffsets;
MVKVectorInline<VkPushConstantRange, 8> _pushConstants;
MVKShaderResourceBinding _pushConstantsMTLResourceIndexes;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
index 265d922..1d1ae2d 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
@@ -47,11 +47,11 @@
for (uint32_t dsIdx = 0; dsIdx < dsCnt; dsIdx++) {
MVKDescriptorSet* descSet = descriptorSets[dsIdx];
uint32_t dslIdx = firstSet + dsIdx;
- auto& dsl = _descriptorSetLayouts[dslIdx];
- dsl.bindDescriptorSet(cmdEncoder, descSet,
- _dslMTLResourceIndexOffsets[dslIdx],
- dynamicOffsets, &pDynamicOffsetIndex);
- setConfigurationResult(dsl.getConfigurationResult());
+ MVKDescriptorSetLayout* dsl = _descriptorSetLayouts[dslIdx];
+ dsl->bindDescriptorSet(cmdEncoder, descSet,
+ _dslMTLResourceIndexOffsets[dslIdx],
+ dynamicOffsets, &pDynamicOffsetIndex);
+ setConfigurationResult(dsl->getConfigurationResult());
}
}
@@ -60,9 +60,9 @@
MVKVector<VkWriteDescriptorSet>& descriptorWrites,
uint32_t set) {
clearConfigurationResult();
- auto& dsl = _descriptorSetLayouts[set];
- dsl.pushDescriptorSet(cmdEncoder, descriptorWrites, _dslMTLResourceIndexOffsets[set]);
- setConfigurationResult(dsl.getConfigurationResult());
+ MVKDescriptorSetLayout* dsl = _descriptorSetLayouts[set];
+ dsl->pushDescriptorSet(cmdEncoder, descriptorWrites, _dslMTLResourceIndexOffsets[set]);
+ setConfigurationResult(dsl->getConfigurationResult());
}
// A null cmdEncoder can be passed to perform a validation pass
@@ -71,9 +71,9 @@
uint32_t set,
const void* pData) {
clearConfigurationResult();
- auto& dsl = _descriptorSetLayouts[set];
- dsl.pushDescriptorSet(cmdEncoder, descUpdateTemplate, pData, _dslMTLResourceIndexOffsets[set]);
- setConfigurationResult(dsl.getConfigurationResult());
+ MVKDescriptorSetLayout* dsl = _descriptorSetLayouts[set];
+ dsl->pushDescriptorSet(cmdEncoder, descUpdateTemplate, pData, _dslMTLResourceIndexOffsets[set]);
+ setConfigurationResult(dsl->getConfigurationResult());
}
void MVKPipelineLayout::populateShaderConverterContext(SPIRVToMSLConversionConfiguration& context) {
@@ -82,9 +82,9 @@
// Add resource bindings defined in the descriptor set layouts
uint32_t dslCnt = (uint32_t)_descriptorSetLayouts.size();
for (uint32_t dslIdx = 0; dslIdx < dslCnt; dslIdx++) {
- _descriptorSetLayouts[dslIdx].populateShaderConverterContext(context,
- _dslMTLResourceIndexOffsets[dslIdx],
- dslIdx);
+ _descriptorSetLayouts[dslIdx]->populateShaderConverterContext(context,
+ _dslMTLResourceIndexOffsets[dslIdx],
+ dslIdx);
}
// Add any resource bindings used by push-constants
@@ -113,16 +113,16 @@
// with each DSL as it is added. The final accumulation of resource index offsets
// becomes the resource index offsets that will be used for push contants.
- // According to the Vulkan spec, VkDescriptorSetLayout is intended to be consumed when
- // passed to any Vulkan function, and may be safely destroyed by app immediately after.
- // In order for this pipeline layout to retain the content of a VkDescriptorSetLayout,
- // this pipeline holds onto copies of the MVKDescriptorSetLayout instances, so that the
- // originals created by the app can be safely destroyed.
+ // According to the Vulkan spec, VkDescriptorSetLayout is intended to be consumed when passed
+ // to any Vulkan function, and may be safely destroyed by app immediately after. In order for
+ // this pipeline layout to retain the VkDescriptorSetLayout, the MVKDescriptorSetLayout
+ // instance is retained, so that it will live on here after it has been destroyed by the API.
_descriptorSetLayouts.reserve(pCreateInfo->setLayoutCount);
for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) {
MVKDescriptorSetLayout* pDescSetLayout = (MVKDescriptorSetLayout*)pCreateInfo->pSetLayouts[i];
- _descriptorSetLayouts.push_back(*pDescSetLayout);
+ pDescSetLayout->retain();
+ _descriptorSetLayouts.push_back(pDescSetLayout);
_dslMTLResourceIndexOffsets.push_back(_pushConstantsMTLResourceIndexes);
_pushConstantsMTLResourceIndexes += pDescSetLayout->_mtlResourceCounts;
}
@@ -150,6 +150,10 @@
}
}
+MVKPipelineLayout::~MVKPipelineLayout() {
+ for (auto dsl : _descriptorSetLayouts) { dsl->release(); }
+}
+
#pragma mark -
#pragma mark MVKPipeline
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm
index 9fb29be..60d4532 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSync.mm
@@ -80,15 +80,9 @@
#pragma mark -
#pragma mark MVKSemaphore
-bool MVKSemaphore::wait(uint64_t timeout) {
- bool isDone = _blocker.wait(timeout, true);
- if ( !isDone && timeout > 0 ) { reportError(VK_TIMEOUT, "Vulkan semaphore timeout after %llu nanoseconds.", timeout); }
- return isDone;
-}
+bool MVKSemaphore::wait(uint64_t timeout) { return _blocker.wait(timeout, true); }
-void MVKSemaphore::signal() {
- _blocker.release();
-}
+void MVKSemaphore::signal() { _blocker.release(); }
void MVKSemaphore::encodeWait(id<MTLCommandBuffer> cmdBuff) {
[cmdBuff encodeWaitForEvent: _mtlEvent value: _mtlEventValue];
@@ -254,12 +248,7 @@
((MVKFence*)pFences[i])->addSitter(&fenceSitter);
}
- if ( !fenceSitter.wait(timeout) ) {
- rslt = VK_TIMEOUT;
- if (timeout > 0) {
- device->reportError(rslt, "Vulkan fence timeout after %llu nanoseconds.", timeout);
- }
- }
+ if ( !fenceSitter.wait(timeout) ) { rslt = VK_TIMEOUT; }
for (uint32_t i = 0; i < fenceCount; i++) {
((MVKFence*)pFences[i])->removeSitter(&fenceSitter);