I'm fairly sure i've ran into an anomaly with the D3D9 driver. When I run the following code (which basically does nothing but loading/removing textures) I get very different results when it comes to memory with D3D9 and OpenGL.
If I load/draw a big texture for a few frames then remove it and load/draw a much smaller one there is some kind of remote memory usage with D3D9. If the small texture uses like 10Mo of ram, and the big one like 250Mo or something, then when the code goes back to drawing the small one, even tho I called removeAllTextures(), the application still uses about 150Mo when it should be back to ~25Mo or something. Obviously all textures should be removed at some point after calling removeAllTextures() but once the big texture has been loaded and drawn multiple times, the memory usage will never go back down. And If I only draw the small one then the big one then do not draw the small one again and just keep calling only removeAllTextures everyframe, the memory usage still won't go back to 25Mo. It looks like no matter what I do, once i've loaded and drawn the big texture a few times I won't be able to have the same behavior as OpenGL unless I drop and recreate the device.
When using OpenGL, there is no such issue I can load/remove textures in every possible way, once i can removeAllTextures, every bit of memory is free'ed.
Same thing seems to happen for all texture sizes, I just used a very big one in order to be able to easily notice the difference.
Same issue with both 1.8.3 and trunk version, however the memory usage is smaller with the trunk one (ie : like 120Mo instead of 170Mo) but still a lot higher than the OpenGL driver.
Note that it's not a proper memory leak, the memory usage does not grow indefinitely, there seems to be some kind of cap, I've tried to use the following code but as an infinite loop (the code would alternate everyframe between the 2 textures) and after several minutes, the memory usage was still the same when drawing the small texture (150Mo or something), it's way higher than expected but it does not grow forever. It looked like it depended on the maximum size of the biggest texture drawn or something.
In the end I wouldn't say it is too much of an issue (besides the fact that your application might use more memory with the D3D9 driver than the OpenGL one) nor that I know where it comes from or how it behaves exactly or even if it's a bug but still I thought it would be worth posting because when you call removeAllTextures you expect the memory to actually be free'ed and not to have 150Mo+ to still be remotely used.
The only way i've found so far to reset the memory usage was to drop/recreate the D3D9 device.
I did not post in the bug section because i'm not sure if it is the normal behavior or not but to me it does not seem normal at all. If it is then i'd really like, if possible, to get some sort of explanation because this has been bothering me for a while now.
I used the following BMPs :
Small texture : http://technologie-f-mauriac.jimdo.com/ ... 1395577376
Big texture : http://ilab.engr.utk.edu/ilabdocs/Epilo ... %20dpi.bmp
Code: Select all
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
int main()
{
IrrlichtDevice *device =
createDevice(video::EDT_DIRECT3D9, dimension2d<u32>(640, 480));
if (!device)
return 1;
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
int j = 0;
ITexture *t;
while(device->run())
{
if(j<20){
driver->removeAllTextures();
t = driver->getTexture("pathToSmallTexture");
j++;}
else if(j<30){
driver->removeAllTextures();
t = driver->getTexture("pathToBigTexture");
j++;}
else{
driver->removeAllTextures();
t = driver->getTexture("pathToSmallTexture");}
driver->beginScene(true, true, SColor(255,100,101,140));
driver->draw2DImage(t, vector2d<s32>(0, 0));
driver->endScene();
}
device->drop();
return 0;
}