Skip to content

Commit 6ce8fd0

Browse files
authored
Release all images in MetalTextureHandler::releaseRenderResources (#2316)
This PR addresses #2303. This brings the MetalTextureHandler inline with the GLTextureHandler for releasing all the images when `nullptr` is passed. Without this - both CPU and Metal texture memory is being leaked if the image caches are flushed. Recursively releasing the resources fixes the Metal texture memory leak, but that just highlighted the CPU side memory leak. This is due to the MetalTextureHandler also retaining an `ImagePtr` in `_imageBindingInfo`. Removing the `ImagePtr` from this storage fixes the memory leak, and it doesn't seem to be necessary to store the image, the only thing the image is used for is to access the resource ID - which is the same as the key to the `unordered_map`.
1 parent 75e372f commit 6ce8fd0

2 files changed

Lines changed: 16 additions & 12 deletions

File tree

source/MaterialXRenderMsl/MetalTextureHandler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class MX_RENDERMSL_API MetalTextureHandler : public ImageHandler
8989
std::vector<unsigned int> _boundTextureLocations;
9090

9191
std::unordered_map<unsigned int, id<MTLTexture>> _metalTextureMap;
92-
std::unordered_map<unsigned int, std::pair<ImagePtr, ImageSamplingProperties>> _imageBindingInfo;
92+
std::unordered_map<unsigned int, ImageSamplingProperties> _imageBindingInfo;
9393
std::unordered_map<ImageSamplingProperties, id<MTLSamplerState>, ImageSamplingKeyHasher> _imageSamplerStateMap;
9494

9595
id<MTLDevice> _device = nil;

source/MaterialXRenderMsl/MetalTextureHandler.mm

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
return false;
3030
}
3131
}
32-
_imageBindingInfo[image->getResourceId()] = std::make_pair(image, samplingProperties);
32+
_imageBindingInfo[image->getResourceId()] = samplingProperties;
3333
return true;
3434
}
3535

@@ -72,7 +72,7 @@
7272
_boundTextureLocations[textureUnit] = image->getResourceId();
7373

7474
[renderCmdEncoder setFragmentTexture:_metalTextureMap[image->getResourceId()] atIndex:textureUnit];
75-
[renderCmdEncoder setFragmentSamplerState:getSamplerState(_imageBindingInfo[image->getResourceId()].second) atIndex:textureUnit];
75+
[renderCmdEncoder setFragmentSamplerState:getSamplerState(_imageBindingInfo[image->getResourceId()]) atIndex:textureUnit];
7676

7777
return true;
7878
}
@@ -90,15 +90,10 @@
9090

9191
id<MTLTexture> MetalTextureHandler::getMTLTextureForImage(unsigned int index) const
9292
{
93-
auto imageInfo = _imageBindingInfo.find(index);
94-
if (imageInfo != _imageBindingInfo.end())
93+
auto metalTexture = _metalTextureMap.find(index);
94+
if (metalTexture != _metalTextureMap.end())
9595
{
96-
if (!imageInfo->second.first)
97-
return nil;
98-
99-
auto metalTexture = _metalTextureMap.find(imageInfo->second.first->getResourceId());
100-
if (metalTexture != _metalTextureMap.end())
101-
return metalTexture->second;
96+
return metalTexture->second;
10297
}
10398

10499
return nil;
@@ -109,7 +104,7 @@
109104
auto imageInfo = _imageBindingInfo.find(index);
110105
if (imageInfo != _imageBindingInfo.end())
111106
{
112-
return getSamplerState(imageInfo->second.second);
107+
return getSamplerState(imageInfo->second);
113108
}
114109
return nil;
115110
}
@@ -281,7 +276,16 @@
281276
void MetalTextureHandler::releaseRenderResources(ImagePtr image)
282277
{
283278
if (!image)
279+
{
280+
for (auto iter : _imageCache)
281+
{
282+
if (iter.second)
283+
{
284+
releaseRenderResources(iter.second);
285+
}
286+
}
284287
return;
288+
}
285289

286290
if (image->getResourceId() == MslProgram::UNDEFINED_METAL_RESOURCE_ID)
287291
{

0 commit comments

Comments
 (0)