From fa77f686d85eb1ab443f7603c925206614ec299b Mon Sep 17 00:00:00 2001 From: Jan Sikorski Date: Thu, 7 Nov 2024 11:08:26 +0100 Subject: [PATCH] Put resources in residency sets --- .../Commands/MVKCommandEncoderState.mm | 1 + .../Commands/MVKMTLBufferAllocation.mm | 2 ++ MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm | 6 +++++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 23 +++++++++++++++++++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 14 +++++++++++ .../MoltenVK/GPUObjects/MVKDeviceMemory.mm | 3 ++- MoltenVK/MoltenVK/GPUObjects/MVKImage.mm | 12 ++++++---- MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm | 1 + 8 files changed, 57 insertions(+), 5 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index 7a0de21ae..d6687f069 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -681,6 +681,7 @@ - (void)setDepthBoundsTestAMD:(BOOL)enable minDepth:(float)minDepth maxDepth:(fl auto* dslBind = dsLayout->getBindingAt(dslBindIdx); if (dslBind->getApplyToStage(stage) && shaderBindingUsage.getBit(dslBindIdx)) { shouldBindArgBuffToStage = true; + if (getDevice()->hasResidencySet()) continue; uint32_t elemCnt = dslBind->getDescriptorCount(descSet->getVariableDescriptorCount()); for (uint32_t elemIdx = 0; elemIdx < elemCnt; elemIdx++) { uint32_t descIdx = dslBind->getDescriptorIndex(elemIdx); diff --git a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm index 10ee00e38..54a816c9e 100644 --- a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm +++ b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.mm @@ -46,6 +46,7 @@ void MVKMTLBufferAllocationPool::addMTLBuffer() { MTLResourceOptions mbOpts = (_mtlStorageMode << MTLResourceStorageModeShift) | MTLResourceCPUCacheModeDefaultCache; _mtlBuffers.push_back({ [getMTLDevice() newBufferWithLength: _mtlBufferLength options: mbOpts], 0 }); + getDevice()->makeResident(_mtlBuffers.back().mtlBuffer); _nextOffset = 0; } @@ -106,6 +107,7 @@ MVKMTLBufferAllocationPool::~MVKMTLBufferAllocationPool() { for (uint32_t bufferIndex = 0; bufferIndex < _mtlBuffers.size(); ++bufferIndex) { + getDevice()->removeResidency(_mtlBuffers[bufferIndex].mtlBuffer); [_mtlBuffers[bufferIndex].mtlBuffer release]; } _mtlBuffers.clear(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm index a7cd05595..82581be1b 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm @@ -185,6 +185,7 @@ _mtlBuffer = [_deviceMemory->getMTLHeap() newBufferWithLength: getByteCount() options: _deviceMemory->getMTLResourceOptions() offset: _deviceMemoryOffset]; // retained + getDevice()->makeResident(_mtlBuffer); propagateDebugName(); return _mtlBuffer; } else { @@ -202,6 +203,7 @@ _mtlBufferCache = [getMTLDevice() newBufferWithLength: getByteCount() options: MTLResourceStorageModeManaged]; // retained + getDevice()->makeResident(_mtlBufferCache); flushToDevice(_deviceMemoryOffset, _byteCount); } #endif @@ -268,8 +270,10 @@ void MVKBuffer::detachMemory() { if (_deviceMemory) { _deviceMemory->removeBuffer(this); } _deviceMemory = nullptr; + if (_mtlBuffer) getDevice()->removeResidency(_mtlBuffer); [_mtlBuffer release]; _mtlBuffer = nil; + if (_mtlBufferCache) getDevice()->removeResidency(_mtlBufferCache); [_mtlBufferCache release]; _mtlBufferCache = nil; } @@ -327,6 +331,7 @@ _mtlTexture = [mtlBuff newTextureWithDescriptor: mtlTexDesc offset: mtlBuffOffset bytesPerRow: _mtlBytesPerRow]; + getDevice()->makeResident(_mtlTexture); propagateDebugName(); } return _mtlTexture; @@ -390,6 +395,7 @@ // Potentially called twice, from destroy() and destructor, so ensure everything is nulled out. void MVKBufferView::detachMemory() { + if (_mtlTexture) getDevice()->removeResidency(_mtlTexture); [_mtlTexture release]; _mtlTexture = nil; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 19a27bf70..06013e0e5 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -451,6 +451,7 @@ class MVKPhysicalDevice : public MVKDispatchableVulkanAPIObject { MVKInstance* _mvkInstance; id _mtlDevice; + id _mtlResidencySet; const MVKMTLDeviceCapabilities _gpuCapabilities; const MVKExtensionList _supportedExtensions; MVKPixelFormats _pixelFormats; @@ -819,6 +820,27 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { /** Returns the Metal objects underpinning the Vulkan objects indicated in the pNext chain of pMetalObjectsInfo. */ void getMetalObjects(VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); + inline void makeResident(id allocation) { + @synchronized(_residencySet) { + [_residencySet addAllocation: allocation]; + [_residencySet commit]; + } + } + + inline void removeResidency(id allocation) { + @synchronized(_residencySet) { + [_residencySet removeAllocation:allocation]; + [_residencySet commit]; + } + } + + inline void addResidencySet(id queue) { + if (_residencySet) [queue addResidencySet:_residencySet]; + } + + inline bool hasResidencySet() { + return _residencySet != nil; + } #pragma mark Construction @@ -916,6 +938,7 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { id _globalVisibilityResultMTLBuffer = nil; id _defaultMTLSamplerState = nil; id _dummyBlitMTLBuffer = nil; + id _residencySet = nil; uint32_t _globalVisibilityQueryCount = 0; int _capturePipeFileDesc = -1; bool _isPerformanceTracking = false; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 7b049bce6..fd8042332 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -5237,6 +5237,19 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope // Create the command queues void MVKDevice::initQueues(const VkDeviceCreateInfo* pCreateInfo) { + MTLResidencySetDescriptor *setDescriptor; + setDescriptor = [MTLResidencySetDescriptor new]; + setDescriptor.label = @"Primary residency set"; + setDescriptor.initialCapacity = 256; + + NSError *error; + _residencySet = [_physicalDevice->getMTLDevice() newResidencySetWithDescriptor:setDescriptor + error:&error]; + if (error) { + reportMessage(MVK_CONFIG_LOG_LEVEL_ERROR, "Error allocating residency set: %s", error.description.UTF8String); + } + [setDescriptor release]; + auto qFams = _physicalDevice->getQueueFamilies(); uint32_t qrCnt = pCreateInfo->queueCreateInfoCount; for (uint32_t qrIdx = 0; qrIdx < qrCnt; qrIdx++) { @@ -5303,6 +5316,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope for (auto fence: _stageBarriers) [fence release]; for (auto &fences: _activeBarriers) for (auto fence: fences) [fence release]; + [_residencySet release]; [_globalVisibilityResultMTLBuffer release]; [_defaultMTLSamplerState release]; [_dummyBlitMTLBuffer release]; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm index 565fc2edc..8bcee74eb 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.mm @@ -249,7 +249,7 @@ } if (!_mtlBuffer) { return false; } _pMemory = isMemoryHostAccessible() ? _mtlBuffer.contents : nullptr; - + getDevice()->makeResident(_mtlBuffer); propagateDebugName(); return true; @@ -428,6 +428,7 @@ auto imgCopies = _imageMemoryBindings; for (auto& img : imgCopies) { img->bindDeviceMemory(nullptr, 0); } + if (_mtlBuffer) getDevice()->removeResidency(_mtlBuffer); [_mtlBuffer release]; _mtlBuffer = nil; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 93507ebf6..950da9b37 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -76,7 +76,7 @@ } [mtlTexDesc release]; // temp release - + _image->getDevice()->makeResident(_mtlTexture); propagateDebugName(); } return _mtlTexture; @@ -101,6 +101,7 @@ } void MVKImagePlane::releaseMTLTexture() { + if (_mtlTexture) _image->getDevice()->removeResidency(_mtlTexture); [_mtlTexture release]; _mtlTexture = nil; @@ -436,7 +437,8 @@ } if (!_mtlTexelBuffer) { return reportError(VK_ERROR_OUT_OF_DEVICE_MEMORY, "Could not create an MTLBuffer for an image that requires a buffer backing store. Images that can be used for atomic accesses must have a texel buffer backing them."); - } + } + getDevice()->makeResident(_mtlTexelBuffer); _mtlTexelBufferOffset = 0; _ownsTexelBuffer = true; } @@ -444,7 +446,6 @@ _mtlTexelBuffer = _deviceMemory->_mtlBuffer; _mtlTexelBufferOffset = getDeviceMemoryOffset(); } - flushToDevice(getDeviceMemoryOffset(), getByteCount()); return _deviceMemory->addImageMemoryBinding(this); } @@ -541,7 +542,10 @@ MVKImageMemoryBinding::~MVKImageMemoryBinding() { if (_deviceMemory) { _deviceMemory->removeImageMemoryBinding(this); } - if (_ownsTexelBuffer) { [_mtlTexelBuffer release]; } + if (_ownsTexelBuffer) { + if (_ownsTexelBuffer) _image->getDevice()->removeResidency(_mtlTexelBuffer); + [_mtlTexelBuffer release]; + } } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm index 8fe78d30e..db363634d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm @@ -339,6 +339,7 @@ // Retrieves and initializes the Metal command queue and Xcode GPU capture scopes void MVKQueue::initMTLCommandQueue() { _mtlQueue = _queueFamily->getMTLCommandQueue(_index); // not retained (cached in queue family) + _device->addResidencySet(_mtlQueue); _submissionCaptureScope = new MVKGPUCaptureScope(this); if (_queueFamily->getIndex() == getMVKConfig().defaultGPUCaptureScopeQueueFamilyIndex &&