mirror of
https://github.com/love2d/love.git
synced 2026-08-19 12:14:20 +02:00
improve logic for detecting when Texture:generateMipmaps is supported
This commit is contained in:
@@ -232,8 +232,13 @@ Texture::Texture(Graphics *gfx, const Settings &settings, const Slices *slices)
|
|||||||
if (mipmapsMode != MIPMAPS_NONE)
|
if (mipmapsMode != MIPMAPS_NONE)
|
||||||
mipmapCount = getTotalMipmapCount(pixelWidth, pixelHeight, depth);
|
mipmapCount = getTotalMipmapCount(pixelWidth, pixelHeight, depth);
|
||||||
|
|
||||||
if (mipmapsMode == MIPMAPS_AUTO && isPixelFormatDepthStencil(format))
|
const char *miperr = nullptr;
|
||||||
throw love::Exception("Automatic mipmap generation cannot be used for depth/stencil textures.");
|
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)
|
if (pixelWidth <= 0 || pixelHeight <= 0 || layers <= 0 || depth <= 0)
|
||||||
throw love::Exception("Texture dimensions must be greater than 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();
|
generateMipmaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::generateMipmaps()
|
bool Texture::supportsGenerateMipmaps(const char *&outReason) const
|
||||||
{
|
{
|
||||||
if (getMipmapCount() == 1 || getMipmapsMode() == MIPMAPS_NONE)
|
if (getMipmapsMode() == MIPMAPS_NONE)
|
||||||
throw love::Exception("generateMipmaps can only be called on a Texture which was created with mipmaps enabled.");
|
{
|
||||||
|
outReason = "generateMipmaps can only be called on a Texture which was created with mipmaps enabled.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isPixelFormatCompressed(format))
|
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))
|
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))
|
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();
|
generateMipmapsInternal();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,6 +311,7 @@ protected:
|
|||||||
void uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y);
|
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;
|
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 generateMipmapsInternal() = 0;
|
||||||
virtual void readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect) = 0;
|
virtual void readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -269,8 +269,6 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void *data, size_t s
|
|||||||
|
|
||||||
void Texture::generateMipmapsInternal()
|
void Texture::generateMipmapsInternal()
|
||||||
{ @autoreleasepool {
|
{ @autoreleasepool {
|
||||||
// TODO: alternate method for non-color-renderable and non-filterable
|
|
||||||
// pixel formats.
|
|
||||||
id<MTLBlitCommandEncoder> encoder = Graphics::getInstance()->useBlitEncoder();
|
id<MTLBlitCommandEncoder> encoder = Graphics::getInstance()->useBlitEncoder();
|
||||||
[encoder generateMipmapsForTexture:texture];
|
[encoder generateMipmapsForTexture:texture];
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user