Merge pull request #1073 from cdavis5e/aliasable-dedicated-alloc

Allow multiple images for dedicated allocs of aliasabled images.
This commit is contained in:
Bill Hollings 2020-09-28 11:50:04 -04:00 committed by GitHub
commit 299a937887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 6 deletions

View File

@ -154,8 +154,9 @@ VkResult MVKDeviceMemory::addImageMemoryBinding(MVKImageMemoryBinding* mvkImg) {
lock_guard<mutex> lock(_rezLock);
// If a dedicated alloc, ensure this image is the one and only image
// I am dedicated to.
if (_isDedicated && (_imageMemoryBindings.empty() || _imageMemoryBindings[0] != mvkImg) ) {
// I am dedicated to. If my image is aliasable, though, allow other aliasable
// images to bind to me.
if (_isDedicated && (_imageMemoryBindings.empty() || !(contains(_imageMemoryBindings, mvkImg) || (_imageMemoryBindings[0]->_image->getIsAliasable() && mvkImg->_image->getIsAliasable()))) ) {
return reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "Could not bind VkImage %p to a VkDeviceMemory dedicated to resource %p. A dedicated allocation may only be used with the resource it was dedicated to.", mvkImg, getDedicatedResource() );
}

View File

@ -187,6 +187,9 @@ public:
/** Returns whether this image has a linear memory layout. */
bool getIsLinear() { return _isLinear; }
/** Returns whether this image is allowed to alias another image. */
bool getIsAliasable() { return _isAliasable; }
/**
* Returns the 3D extent of this image at the base mipmap level.
* For 2D or cube images, the Z component will be 1.

View File

@ -62,6 +62,13 @@ id<MTLTexture> MVKImagePlane::getMTLTexture() {
newTextureWithDescriptor: mtlTexDesc
offset: memoryBinding->getDeviceMemoryOffset() + _subresources[0].layout.offset];
if (_image->_isAliasable) { [_mtlTexture makeAliasable]; }
} else if (_image->_isAliasable && memoryBinding->_deviceMemory->isDedicatedAllocation() &&
!contains(memoryBinding->_deviceMemory->_imageMemoryBindings, memoryBinding)) {
// This is a dedicated allocation, but it belongs to another aliasable image.
// In this case, use the MTLTexture from the memory's dedicated image.
// We know the other image must be aliasable, or I couldn't have been bound
// to its memory: the memory object wouldn't allow it.
_mtlTexture = [memoryBinding->_deviceMemory->_imageMemoryBindings[0]->_image->getMTLTexture(_planeIndex, mtlTexDesc.pixelFormat) retain];
} else {
_mtlTexture = [_image->getMTLDevice() newTextureWithDescriptor: mtlTexDesc];
}
@ -113,6 +120,8 @@ MTLTextureDescriptor* MVKImagePlane::newMTLTextureDescriptor() {
}
#endif
MVKImageMemoryBinding* memoryBinding = getMemoryBinding();
VkExtent3D extent = _image->getExtent3D(_planeIndex, 0);
MTLTextureDescriptor* mtlTexDesc = [MTLTextureDescriptor new]; // retained
mtlTexDesc.pixelFormat = mtlPixFmt;
@ -123,7 +132,12 @@ MTLTextureDescriptor* MVKImagePlane::newMTLTextureDescriptor() {
mtlTexDesc.mipmapLevelCount = _image->_mipLevels;
mtlTexDesc.sampleCount = mvkSampleCountFromVkSampleCountFlagBits(_image->_samples);
mtlTexDesc.arrayLength = _image->_arrayLayers;
mtlTexDesc.usageMVK = _image->getPixelFormats()->getMTLTextureUsage(_image->_usage, mtlPixFmt, minUsage, _image->_isLinear, _image->_hasMutableFormat, _image->_hasExtendedUsage);
if (_image->_isAliasable && memoryBinding->_deviceMemory && memoryBinding->_deviceMemory->isDedicatedAllocation()) {
// Unfortunately, in this instance, we must presume the texture can be used for anything.
mtlTexDesc.usageMVK = MTLTextureUsageUnknown;
} else {
mtlTexDesc.usageMVK = _image->getPixelFormats()->getMTLTextureUsage(_image->_usage, mtlPixFmt, minUsage, _image->_isLinear, _image->_hasMutableFormat, _image->_hasExtendedUsage);
}
mtlTexDesc.storageModeMVK = _image->getMTLStorageMode();
mtlTexDesc.cpuCacheMode = _image->getMTLCPUCacheMode();
@ -831,6 +845,7 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
MVKPixelFormats* pixFmts = getPixelFormats();
_vkFormat = pCreateInfo->format;
_usage = pCreateInfo->usage;
_isAliasable = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_ALIAS_BIT);
_hasMutableFormat = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT);
_hasExtendedUsage = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_EXTENDED_USAGE_BIT);
@ -876,7 +891,6 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
[mtlTexDesc release];
memoryBinding->_byteCount += sizeAndAlign.size;
memoryBinding->_byteAlignment = std::max(memoryBinding->_byteAlignment, (VkDeviceSize)sizeAndAlign.align);
_isAliasable = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_ALIAS_BIT);
} else if (_isLinearForAtomics && _device->_pMetalFeatures->placementHeaps) {
NSUInteger bufferLength = 0;
for (uint32_t mipLvl = 0; mipLvl < _mipLevels; mipLvl++) {
@ -886,7 +900,6 @@ MVKImage::MVKImage(MVKDevice* device, const VkImageCreateInfo* pCreateInfo) : MV
MTLSizeAndAlign sizeAndAlign = [_device->getMTLDevice() heapBufferSizeAndAlignWithLength: bufferLength options: MTLResourceStorageModePrivate];
memoryBinding->_byteCount += sizeAndAlign.size;
memoryBinding->_byteAlignment = std::max(std::max(memoryBinding->_byteAlignment, _rowByteAlignment), (VkDeviceSize)sizeAndAlign.align);
_isAliasable = mvkIsAnyFlagEnabled(pCreateInfo->flags, VK_IMAGE_CREATE_ALIAS_BIT);
} else {
for (uint32_t mipLvl = 0; mipLvl < _mipLevels; mipLvl++) {
VkExtent3D mipExtent = getExtent3D(planeIndex, mipLvl);

View File

@ -470,7 +470,7 @@ void mvkReleaseContainerContents(C& container) {
/** Returns whether the container contains an item equal to the value. */
template<class C, class T>
bool contains(const C& container, const T& val) {
bool contains(C& container, const T& val) {
for (const T& cVal : container) { if (cVal == val) { return true; } }
return false;
}