From 304bf8bb83a11e04b41f5abd6be8b6762596510c Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Tue, 16 Jul 2024 17:44:58 -0300 Subject: [PATCH] metal: fix texture memory tracking --- src/modules/graphics/Texture.cpp | 31 +++++++++++++++++++++---- src/modules/graphics/Texture.h | 2 +- src/modules/graphics/metal/Texture.mm | 2 ++ src/modules/graphics/opengl/Texture.cpp | 24 +++---------------- src/modules/graphics/vulkan/Texture.cpp | 21 +++-------------- 5 files changed, 35 insertions(+), 45 deletions(-) diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index dde61a53a..b82d2552f 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -450,7 +450,7 @@ Texture::Texture(Graphics *gfx, Texture *base, const ViewSettings &viewsettings) Texture::~Texture() { - setGraphicsMemorySize(0); + updateGraphicsMemorySize(false); if (this == rootView.texture) --textureCount; @@ -461,13 +461,34 @@ Texture::~Texture() parentView.texture->release(); } -void Texture::setGraphicsMemorySize(int64 bytes) +void Texture::updateGraphicsMemorySize(bool loaded) { + int64 memsize = 0; + + if (loaded) + { + for (int mip = 0; mip < getMipmapCount(); mip++) + { + int w = getPixelWidth(mip); + int h = getPixelHeight(mip); + int slices = getDepth(mip) * layers * (texType == TEXTURE_CUBE ? 6 : 1); + memsize += getPixelFormatSliceSize(format, w, h) * slices; + } + + if (getMSAA() > 1 && isReadable()) + { + int slices = depth * layers * (texType == TEXTURE_CUBE ? 6 : 1); + memsize += getPixelFormatSliceSize(format, pixelWidth, pixelHeight) * slices * getMSAA(); + } + else if (getMSAA() > 1) + memsize *= getMSAA(); + } + totalGraphicsMemory = std::max(totalGraphicsMemory - graphicsMemorySize, (int64) 0); - bytes = std::max(bytes, (int64) 0); - graphicsMemorySize = bytes; - totalGraphicsMemory += bytes; + memsize = std::max(memsize, (int64) 0); + graphicsMemorySize = memsize; + totalGraphicsMemory += memsize; } void Texture::draw(Graphics *gfx, const Matrix4 &m) diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 0f228848f..8f17d0f0d 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -337,7 +337,7 @@ protected: Texture(Graphics *gfx, Texture *base, const ViewSettings &viewsettings); virtual ~Texture(); - void setGraphicsMemorySize(int64 size); + void updateGraphicsMemorySize(bool loaded); void uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y); virtual void uploadByteData(const void *data, size_t size, int level, int slice, const Rect &r) = 0; diff --git a/src/modules/graphics/metal/Texture.mm b/src/modules/graphics/metal/Texture.mm index e880495ae..216656af6 100644 --- a/src/modules/graphics/metal/Texture.mm +++ b/src/modules/graphics/metal/Texture.mm @@ -209,6 +209,8 @@ Texture::Texture(love::graphics::Graphics *gfxbase, id device, const } } + updateGraphicsMemorySize(true); + // Non-readable textures can't have mipmaps (enforced in the base class), // so generateMipmaps here is fine - when they aren't already initialized. if (shouldgeneratemips) diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index bd5b9591b..89ef30f50 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -426,26 +426,6 @@ bool Texture::loadVolatile() return false; } - int64 memsize = 0; - - for (int mip = 0; mip < getMipmapCount(); mip++) - { - int w = getPixelWidth(mip); - int h = getPixelHeight(mip); - int slices = getDepth(mip) * layers * (texType == TEXTURE_CUBE ? 6 : 1); - memsize += getPixelFormatSliceSize(format, w, h) * slices; - } - - if (actualSamples > 1 && isReadable()) - { - int slices = depth * layers * (texType == TEXTURE_CUBE ? 6 : 1); - memsize += getPixelFormatSliceSize(format, pixelWidth, pixelHeight) * slices * actualSamples; - } - else if (actualSamples > 1) - memsize *= actualSamples; - - setGraphicsMemorySize(memsize); - if (!debugName.empty() && (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_2)) { if (texture) @@ -460,6 +440,8 @@ bool Texture::loadVolatile() } } + updateGraphicsMemorySize(true); + return true; } @@ -487,7 +469,7 @@ void Texture::unloadVolatile() renderbuffer = 0; texture = 0; - setGraphicsMemorySize(0); + updateGraphicsMemorySize(false); } void Texture::uploadByteData(const void *data, size_t size, int level, int slice, const Rect &r) diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index ff51a4e49..5129942bc 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -237,23 +237,6 @@ bool Texture::loadVolatile() } } - int64 memsize = 0; - - if (root) - { - for (int mip = 0; mip < getMipmapCount(); mip++) - { - int w = getPixelWidth(mip); - int h = getPixelHeight(mip); - int slices = getDepth(mip) * layerCount; - memsize += getPixelFormatSliceSize(format, w, h) * slices; - } - - memsize *= static_cast(msaaSamples); - } - - setGraphicsMemorySize(memsize); - if (!debugName.empty()) { if (vgfx->getEnabledOptionalInstanceExtensions().debugInfo) @@ -275,6 +258,8 @@ bool Texture::loadVolatile() } } + updateGraphicsMemorySize(true); + return true; } @@ -301,7 +286,7 @@ void Texture::unloadVolatile() textureImage = VK_NULL_HANDLE; textureImageAllocation = VK_NULL_HANDLE; - setGraphicsMemorySize(0); + updateGraphicsMemorySize(false); } Texture::~Texture()