OGRECave / ogre

scene-oriented, flexible 3D engine (C++, Python, C#, Java)
https://ogrecave.github.io/ogre/
MIT License
3.89k stars 960 forks source link

[OGRE-150] DX9 RS Bug: destroying the dummy render window breaks almost all geometry #32

Open paroj opened 8 years ago

paroj commented 8 years ago

[reporter="xavyiy", created="Fri, 22 Feb 2013 16:56:51 +0100"]

This is a big problem since in the Ogre3d DX9 RS you need to destroy the dummy render window before switching to fullscreen any other existent render window (otherwise you get a swap chain expection). (More info: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=58142#p392888 )

The problem seems to be here since Ogre 1.8, I'm sure it worked in 1.7...

I've attached a .cpp which shows the problem, comment the line #136, mRoot->destroyRenderTarget(mWindow), in order to see how it should look!

Hope it's going to be an easy bug to catch!

paroj commented 8 years ago

[author="xavyiy", created="Fri, 22 Feb 2013 17:03:56 +0100"]

New version of main.cpp, now the line containing mRoot->destroyRenderTarget(mWindow); is the #94

paroj commented 8 years ago

[author="wolfmanfx", created="Sun, 24 Feb 2013 19:48:02 +0100"]

I took a look but this one is not a bug by definition as you already saw in the thread its the excepted behavior by the author (Nir). Anyway i will think about it again after 1.9 RC is released.

paroj commented 8 years ago

[author="xavyiy", created="Sun, 24 Feb 2013 21:02:02 +0100"]

The problem is not having to destroy the dummy render window (expected behaviour, explained by Nir), the problem is that a lot of geometry (but not all, billboards and some overlay elements are ok) is messed up no matter of the resource creation policy.

I'm almost sure it was working on 1.7.X, dunno if Nir patch was present in 1.7 or directly in 1.8 (it's here since 4 years ago). I'll test an old build (1.7.4) and make sure it was working before.

Maybe I am missing something in the Nir explanation :/

paroj commented 8 years ago

[author="wolfmanfx", created="Sun, 24 Feb 2013 21:33:32 +0100"]

If you have sometime you could bisect - so you could locate the rev which broke the behavior if its broken because i am also not sure if nir pushed it into 1.7 (but it could be possible)

paroj commented 8 years ago

[author="xavyiy", created="Sun, 24 Feb 2013 23:25:58 +0100"]

As far as I can see, Nir patch was introduced in 1.6:

http://sourceforge.net/p/ogre/patches/980/
http://www.ogre3d.org/forums/viewtopic.php?f=11&t=47621

So I don't think it's a problem related to this patch. I'll test if all was working in 1.7.4 and comment here the result. The problem is that the transition from 1.7 to 1.8 was not very clean, so it may take some time with by bisecting.

I'll keep you updated!

paroj commented 8 years ago

[author="xavyiy", created="Mon, 25 Feb 2013 00:21:54 +0100"]

Confirmed, in 1.7.4 all was working as expected. (So the bug is between 1.7.4 and 1.8)

In a friend's computer my editor has some visual artifacts under DX9, which are very probably related to this bug (at first Ogre::ManualObject's aren't shown, and then all expect billboards (like the bug I reproduce in the attached file). Nvidia GTX 470 with latest drivers. The weird thing is that in another computer with the same HW it works!

Related??? ---> http://www.ogre3d.org/forums/viewtopic.php?f=2&t=73272

What do you think? It should be a change in the DX9 RS (in OpenGL all works as expected)

paroj commented 8 years ago

[author="xavyiy", created="Mon, 25 Feb 2013 23:04:50 +0100"]

I've some more info.

Using an old build of the Paradise Engine, under Ogre 1.7.4, the problem with the non-visible manual objects is not present while the problem exists with Ogre 1.8.2, so it's a DX9 RS bug for sure, introduced between 1.7.4 and 1.8.X.

I'm sure this problem commented on the forum http://www.ogre3d.org/forums/viewtopic.php?f=2&t=73272 is directly related with this bug. The same problem, also due to migrating from 1.7.4 to 1.8.1.

The weird thing is that it does not depend of the graphic card or the driver version: Nvidia GTX 470 tested with 314.07, 310.90, 306.97 and 301.42 can reproduce this issue, while with the same card (or any other Nvidia card) with the same drivers are fine in all the other computers I've tested it.

While I'm convinced the root of the problem is the same than the bug described in this entry, I don't know what kind of bug will raise this kind of problems (and why only with manual objects?).

In the editor I use a dummy render window and then a lot of other render windows for displaying content, in multiple viewports, so it makes sense that it's something handled in a bad way by the DX9 RS when multiple render windows are involved.

For me, the cleverest way for identifying the bug is trying to fix the problem which can be easily reproduced, in all computers, with the main.cpp file attached here. I would like to have some feedback from more experienced people than me in raw DX9 before trying other more annoying solutions like looking for the problem via bisect (too much time for something that maybe is just a creation flag or similar).

Thanks in advance,

Xavier

paroj commented 8 years ago

[author="xavyiy", created="Tue, 26 Feb 2013 00:30:55 +0100"]

Win!!!

Solution:

***1) ogred3d9hardwareindexbuffer.cpp(66):

Change:

if (mUsage & HardwareBuffer::HBU_WRITE_ONLY && D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())

To

if (mUsage & HardwareBuffer::HBU_WRITE_ONLY || D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())

***2) ogred3d9hardwarevertexbuffer.cpp(66)

Change:

if (mUsage & HardwareBuffer::HBU_WRITE_ONLY && D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())

To

if (mUsage & HardwareBuffer::HBU_WRITE_ONLY || D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())

(Replace && by ||)

And also make sure you set selectedRS->setConfigOption("Multi device memory hint", "Auto hardware buffers management"); if using multiple render windows!

paroj commented 8 years ago

[author="dark_sylinc", created="Tue, 26 Feb 2013 00:41:29 +0100"]

The purpose of that "&&" is that D3D9 runtime has it's own backup of everything that is static, so we only need to do our own backups for non-static content (called managed resources in D3D9).
Using an || works, but would heavily increase the memory consumption (more than what is expected).

I did a little research, and the problem may be related to that even though the window has been created, the Device is not fully created; thus when we destroy the last one, it is as if we had only one device active and destroyed it (not fully sure, just a theory)

paroj commented 8 years ago

[author="dark_sylinc", created="Tue, 26 Feb 2013 00:43:37 +0100"]

I just consulted D3D9 documentation, this is probably directly related:

Direct3D 9Ex:
D3DPOOL_MANAGED is valid with IDirect3DDevice9; however, it is not valid with IDirect3DDevice9Ex.

That may explain everything

paroj commented 8 years ago

[author="dark_sylinc", created="Tue, 26 Feb 2013 00:55:43 +0100"]

Gotcha, mistake more, mistake less, the code should be:
( (mUsage & HardwareBuffer::HBU_WRITE_ONLY)!=0 || D3D9RenderSystem::isDirectX9Ex() ) && D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement()

paroj commented 8 years ago

[author="xavyiy", created="Tue, 26 Feb 2013 00:59:02 +0100"]

I'm using 1.8.1, as far as I know the DX9Ex support was added by mattan in 1.9 ( https://bitbucket.org/sinbad/ogre/src/a0b75f490892/RenderSystems/Direct3D9/src/OgreD3D9RenderSystem.cpp ), so it should work with the && too.

Then, the problem should the related with the fact that even if the render window is created the device is not entirely created. Any thoughts?

paroj commented 8 years ago

[author="masterfalcon", created="Tue, 17 Sep 2013 07:15:07 +0200"]

Does replacing the code at line 46 in both files with what Matias suggested resolve the issue?

paroj commented 8 years ago

[author="xavyiy", created="Tue, 17 Sep 2013 20:01:05 +0200"]

No, I'm using this: https://ogre3d.atlassian.net/browse/OGRE-150?focusedCommentId=10702&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-10702

Which "is not correct" (see Matias comment: https://ogre3d.atlassian.net/browse/OGRE-150?focusedCommentId=10703&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-10703 ) but is the only way that I have found to make it working