From c6e09a40f81874e5dade767a868a5d0414bcf5c1 Mon Sep 17 00:00:00 2001 From: davidgyu Date: Tue, 20 Jun 2023 13:45:20 -0700 Subject: [PATCH] Prevent mipmapping of 1x1 textures. In Metal, if a texture has all dimensions being a single texel big the mipmapping call `generateMipmapsForTexture` will fail and throw an exception. So we add a check to the existing one in `HgiMetalBlitCmds::GenerateMipMaps()` which catches this. Thanks to @morteeza for this. Contribution: Apple Fixes #2264 (Internal change: 2281900) --- pxr/imaging/hgiMetal/blitCmds.mm | 39 +++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/pxr/imaging/hgiMetal/blitCmds.mm b/pxr/imaging/hgiMetal/blitCmds.mm index b03dc94aca..48486bbc86 100644 --- a/pxr/imaging/hgiMetal/blitCmds.mm +++ b/pxr/imaging/hgiMetal/blitCmds.mm @@ -444,29 +444,46 @@ } static bool -_HgiCanBeFiltered(HgiFormat format) +_HgiTextureCanBeFiltered(HgiTextureDesc const &descriptor) { - HgiFormat const componentFormat = HgiGetComponentBaseFormat(format); + HgiFormat const componentFormat = + HgiGetComponentBaseFormat(descriptor.format); - switch(componentFormat) { - case HgiFormatInt16: - case HgiFormatUInt16: - case HgiFormatInt32: + if (componentFormat == HgiFormatInt16 || + componentFormat == HgiFormatUInt16 || + componentFormat == HgiFormatInt32) { return false; - default: - return true; } + + GfVec3i const dims = descriptor.dimensions; + switch (descriptor.type) { + case HgiTextureType1D: + case HgiTextureType1DArray: + return (dims[0] > 1); + + case HgiTextureType2D: + case HgiTextureType2DArray: + return (dims[0] > 1 || dims[1] > 1); + + case HgiTextureType3D: + return (dims[0] > 1 || dims[1] > 1 || dims[2] > 1); + + default: + TF_CODING_ERROR("Unsupported HgiTextureType enum value"); + return false; + } + + return false; } void HgiMetalBlitCmds::GenerateMipMaps(HgiTextureHandle const& texture) { HgiMetalTexture* metalTex = static_cast(texture.Get()); + if (metalTex) { - HgiFormat const format = metalTex->GetDescriptor().format; - if (_HgiCanBeFiltered(format)) { + if (_HgiTextureCanBeFiltered(metalTex->GetDescriptor())) { _CreateEncoder(); - // Can fail if the texture format is not filterable. [_blitEncoder generateMipmapsForTexture:metalTex->GetTextureId()]; } }