improve logic for detecting when Texture:generateMipmaps is supported

This commit is contained in:
Alex Szpakowski
2022-02-19 16:34:52 -04:00
parent 6e35ffe2d8
commit bc1c38d361
3 changed files with 44 additions and 10 deletions
+43 -8
View File
@@ -232,8 +232,13 @@ Texture::Texture(Graphics *gfx, const Settings &settings, const Slices *slices)
if (mipmapsMode != MIPMAPS_NONE)
mipmapCount = getTotalMipmapCount(pixelWidth, pixelHeight, depth);
if (mipmapsMode == MIPMAPS_AUTO && isPixelFormatDepthStencil(format))
throw love::Exception("Automatic mipmap generation cannot be used for depth/stencil textures.");
const char *miperr = nullptr;
if (mipmapsMode == MIPMAPS_AUTO && !supportsGenerateMipmaps(miperr))
{
const char *fstr = "unknown";
love::getConstant(format, fstr);
throw love::Exception("Automatic mipmap generation is not supported for textures with the %s pixel format.", fstr);
}
if (pixelWidth <= 0 || pixelHeight <= 0 || layers <= 0 || depth <= 0)
throw love::Exception("Texture dimensions must be greater than 0.");
@@ -511,19 +516,49 @@ void Texture::replacePixels(const void *data, size_t size, int slice, int mipmap
generateMipmaps();
}
void Texture::generateMipmaps()
bool Texture::supportsGenerateMipmaps(const char *&outReason) const
{
if (getMipmapCount() == 1 || getMipmapsMode() == MIPMAPS_NONE)
throw love::Exception("generateMipmaps can only be called on a Texture which was created with mipmaps enabled.");
if (getMipmapsMode() == MIPMAPS_NONE)
{
outReason = "generateMipmaps can only be called on a Texture which was created with mipmaps enabled.";
return false;
}
if (isPixelFormatCompressed(format))
throw love::Exception("generateMipmaps cannot be called on a compressed Texture.");
{
outReason = "generateMipmaps cannot be called on a compressed Texture.";
return false;
}
if (isPixelFormatDepthStencil(format))
throw love::Exception("generateMipmaps cannot be called on a depth/stencil Texture.");
{
outReason = "generateMipmaps cannot be called on a depth/stencil Texture.";
return false;
}
if (isPixelFormatInteger(format))
throw love::Exception("generateMipmaps cannot be called on an integer Texture.");
{
outReason = "generateMipmaps cannot be called on an integer Texture.";
return false;
}
// This should be linear | rt because that's what metal needs, but the above
// code handles textures can't be used as RTs in metal.
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
if (gfx != nullptr && !gfx->isPixelFormatSupported(format, PIXELFORMATUSAGEFLAGS_LINEAR))
{
outReason = "generateMipmaps cannot be called on textures with formats that don't support linear filtering on this system.";
return false;
}
return true;
}
void Texture::generateMipmaps()
{
const char *err = nullptr;
if (!supportsGenerateMipmaps(err))
throw love::Exception("%s", err);
generateMipmapsInternal();
}
+1
View File
@@ -311,6 +311,7 @@ protected:
void uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y);
virtual void uploadByteData(PixelFormat pixelformat, const void *data, size_t size, int level, int slice, const Rect &r) = 0;
bool supportsGenerateMipmaps(const char *&outReason) const;
virtual void generateMipmapsInternal() = 0;
virtual void readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect) = 0;
-2
View File
@@ -269,8 +269,6 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s
void Texture::generateMipmapsInternal()
{ @autoreleasepool {
// TODO: alternate method for non-color-renderable and non-filterable
// pixel formats.
id<MTLBlitCommandEncoder> encoder = Graphics::getInstance()->useBlitEncoder();
[encoder generateMipmapsForTexture:texture];
}}