replacing ITexture by "hardwarelinks"

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

OK I know I am pressing this issue a bit hybrid. But say for instance you had 2 devices each with drivers of different driver types. If you wanted to share scenemanager between those 2 devices, the ONLY thing really stopping you at the moment is the textures (Taking into consideration you would have to modify the scene manager/scene nodes to render to both drivers).
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

Example: User wants to change driver.
Current way: save everything to file, close device, create device, load everything from file, pray that all the save and loads worked properly.
New possible way: drop the driver, create the other driver, wait some time during the sw datas are loaded in new hw buffers automatially if the datas are needed by the hw.

Next Example: Device lost.
Current way: Device calls reset and loads everthing from the sw copies in the hw buffers.
New way: remove all hw buffers, wait some time during the sw datas are loaded in new hw buffers automatially if the datas are needed by the hw.

Of course can the IImage be extended, redesigned or anything else. But this is not the goal of this idea.
The main goal is: seperate the userland sw datas from the device-dependend hw buffers.
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

What do you think about the idea, if we add mipmaps creation and access to the IImage, remove the POOL_MANAGED and the CImage copy of the OGLTexture and change the IImage to fit as a buffer if needed? This way IImage becomes the real datastorage, ITexturelink will only contain the GPU-stored surface so there will be no lockingproblem or higher copycount anymore. Moreover there would be no need for recreating the rtts by the driver manualy like it is actually done. The devicelost/contextchange has to be a bit modified by removing some reset calls and adding just a removeAllTextureLinks. The IImage can get a revisioncounter, so the user can easily check if the IImage has be changed i.e. by the driver to fit the texturecreationflags.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

The problem with adding it to IImage is that sometimes mipmap creation is driver-specific. For example it's better to use D3D's mipmap creation as it's faster and usually better quality.

We would have to always use the crappy software generation in this case, slowing down texture loading times, etc.

I love the idea of not recreating RTTs manually, it's becoming a common hassle.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

Well, we could add a creationflag which indicates, that the driver should use the stored mipmaps if they exists. Else the driver create the mipmaps automatically.

The locking of the hw-buffer is a critical problem because locking the IImage give only access to the sw-buffer without regarding the hw-buffer...any good ideas?

by the way. The interface may be changed to
uploadImage(IImage*) prior addTexture/getTexture/setTexture
downloadImage(IImage*) prior the ITexture::lock/unlock
removeImage(IImage*) prior the removeTexture

just an idea which would solve the lock-problem too. Of course the old methods will remain for some time marked as deprecated.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Why in the world would renaming a method solve a problem. And which problem does have lock and unlock?
Keeping the SW images depending on the texture usage is a pretty good idea, as e.g. locking each frame is not a common thing, but would definitely become infeasible once the memory is deleted each time.
I don't know why RTTs have to be recreated manually, as the whole reset thing is managed by the driver. The content is lost, but using the reset return values it should be possible to check which parts were lost.
And a general advice: These rather ground breaking API changes will not be made due to a very rare event, such as changing the driver on-the-fly. If we get a real benefit from such a change, which helps most of the users, we go for it. But in order to avoid a few internal calls, or to provide a feature which most people would never think of we won't reorganize the whole image system.
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

The current state of the patch does not change the userapi much and with some dumymethodes and some const_cast the user wont even notify the patch if he does not overload ITexture or the driver. Of course the RTT are kept and reloaded by the current system. I just pointed the difference between the current and a possible behavior out.

One problem of this patch is that the user can not access the hw-buffer directly anymore. So somekind of "download"-method is needed. I.e. the IImage::lock(void) can be changed to IImage::lock(IVideoDriver* = 0). If a driver is given the IImage loads the hw-buffer in the sw-buffer. Else the user get access to the sw-buffer without downloading the hw-buffer content first. This can be ONE possible solution but maybe not the best.

Again: goal is a better seperation between userland sw-buffers and driver hw-buffer while keeping the userland behavior as good as possible. I think an in most of the cases not noticeable internal change is possible.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

In the current code, sw and hw images/textures *are* perfectly separated. They don't share anything. So I don't see where we need more separation, IMHO we need more common subparts and interfaces.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

I'm not liking those interface changes, terrible idea...

I'm not giving up though, I still think that if we can solve this cleanly without changing the interface at all then no one can complain.

Let's think for a moment, currently most drivers handle driver-specific textures like this:

Code: Select all

void driverFunction(ITexture* foo)
{
    if(foo->getDriverType() != MY_TYPE)
        throw out some error and return;

    CMyTextureType* bar = dynamic_cast<CMyTextureType*>(foo);
    
    do stuff with the driver specific texture here (Render, etc);
}
Wouldn't it be nicer if we could do:

Code: Select all

void driverFunction(ITexture* foo)
{
   CSharedTexture* foobar = dynamic_cast<CSharedTexture*>(foo);
   CMyTextureType* bar = reinterpret_cast<CMyTextureType*>(foobar->getDriverDependantTexture(MY_TYPE));

    if(!bar)
        throw some error and return;    

    do stuff with the driver specific texture here (Render, etc);
}
getDriverDependantTexture would look like "void* getDriverDependantTexture(E_DRIVER_TYPE)" or maybe "CNullTexture* getDriverDependantTexture(E_DRIVER_TYPE)".

What do you think about that? It can be done without changing the interface at all, and the ITexture would be an identifier suitable for all driver types at the same time.

I know posting a few code snippets isn't helpful, maybe I should create a patch so we can see the full extent of the required changes and all repercussions, etc?
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

That would be possible (and probably also cleaner) if you derive all hw dependent textures from a common base. Something which implements more than ITexture, but does not require the hw dependent stuff. Would make sense if it helps to keep the code better maintainable, and if it also helps in other places it's even better.
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

Well, now im surprised because my solution does:

Code: Select all

void driverFunction(ITexture* foo) 
{ 
   CMyTextureType* bar = static_cast<CMyTextureType*>(getTextureLink(foo)); 

    do stuff with the driver specific texture here (Render, etc); 
} 
So that is the big difference?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

If you had read my text carefully, you'd have noticed that I suggested to *only* create a common base class. This would be a very careful extension without noticeable drawbacks. Which would be a good step if it really helps to make the code cleaner. Your patch changes hundreds other things as well.
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

I mean the difference to Blindsides proposal. But i did not really get your point. "A common class which not requires the hw dependent stuff" sound like IImage to me.
You are right that my idea changes some internal things and the ITexture. But the patch can be changed to keep ITexture as well and derivate it from IImage. I guess i was not abled to show the basic idea of this.

I took a look at the vertex and indexbuffer handling and thought "hey that seperation of sw-buffer and hw-buffer is really nice" and tried to apply this concept to the textures as well. This way the driver stuff can be completely seperated from the sw stuff. At the moment deleting the driver is a bad idea and impossible but if ITexture is no longer a driverdepend class it is no big deal to delete/reset/remove the driver. The next thought was "hey if ITexture is driverindependent, why not merging it with IImage".
Do you think seperating the driverdependent classes from the userland and merging IImage with ITexture isnt it worth? Of course you got a point with the problem what it is a change but i think this change will only harm the additional drivers which implements own ITexture-classes. For the other gui/scene/userlandcases the changes might me reduced to zero.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Merging IImage and ITexture is definitely much more of a difference than adding something between ITexture and COpenGLTexture or any other hw texture. So my suggestion was to start far less intrusive.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

hybrid wrote:That would be possible (and probably also cleaner) if you derive all hw dependent textures from a common base. Something which implements more than ITexture, but does not require the hw dependent stuff. Would make sense if it helps to keep the code better maintainable, and if it also helps in other places it's even better.
Yeah if you noticed in my second code snippet I cast to "CSharedTexture", which is exactly the data structure that you are talking about. It would be hidden away as an implementation class and produce no noticeable difference from the outside. Nox, your "ITextureLink" by definition IS an interface, hence the interface change.

Sigh on another note here I think the op's and my goals are starting to drift apart, maybe I should start a separate discussion?
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Post Reply