I put a lot of profiling code in Ogre's SceneManager::manualRender() function and in SceneManager::_setPass() as well as in the GL_RenderSystem::_render() function etc. Turns out my profiling code in GL_RenderSystem seems to have skewed my profile results.
Profiling the code wasn't giving me many optimization ideas so I took another approach. You know how when you have slow code sometimes you just cut parts of it out till you find out what is slow about it - not the best way to optimize but it can give you some insight when you don't fully understand the design and implementation of libraries you are using (Ogre3d in my case). I could see from the profiling results that it would be good to focus on the Render To Texture(RTT) code so I started removing all the texture look ups in my RTT shader except one and the timing/stuttering issues improved noticeably. I started by adding back in each texture look up one by one to see if adding a certain texture brought back the stuttering/slowness.
It seems that some of my terrain textures were 1024x1024 while the rest were 512x512 (I have 16 terrain textures that get blended in the RTT shader). So I converted those to 512x512 and that helped - and it seems that going above ~8 512x512 textures gives unacceptable slowness and more stuttering. For some reason this is only an issue with OpenGL Render System not DirectX Render System which seems to handle 16 blends fine with no stuttering and faster render times. I may look into this more later because I think I need at least 12 terrain textures.
I might try having several large shared height maps and slope maps - one per cube face to start - instead of one small height map and slope map per terrain patch. I just like the simplicity of the current approach, but it is probably going to be too slow.
Also, I've moved up to the latest Ogre release v1.6.3
Lastly, I tried GLIntercept which was very nice and easy to use and can output textures, all the OpenGL calls and lots more. Did I mention it's free?
At some point I need to start saving rendered terrain textures and height maps and normal maps to disk then reading them back from disk instead of generating them every time.
Saturday, August 8, 2009
Sunday, July 26, 2009
OpenGL Render To Texture 10x Slower than DirectX
That's my main problem right now. It takes roughly 10 - 20 times longer when I call mSceneManager->manualRender() when using OpenGL in Ogre instead of DirectX (9).
After getting my app running in DirectX, I used NVidia Perfhud to debug the framerate spikes - only to find that DirectX is vastly outperforming OpenGL! So now I can't really afford gDEBugger ($800), so I'm stuck with inserting my mini-profiler into the GL_RenderSystem code to figure out what parts are slowing down etc. That will be a good experience and help me get more familiar with Ogre RenderSystem calls.
Misc Notes:
- Make sure you play around with your RenderSystem configuration settings. I had set my Display Frequency to 59 and that caused the framerate to be cut in half. Dunno why I had it set to that value.
- With OpenGL you don't need the RenderSystem to issue _begin() and _end() frame calls, but you do in DirectX.
- Fixed a bug where when writing dynamic textures I was using pointer math and it was messing up my textures in DirectX. I switched to using array notation and it fixed the issue. Haven't spent much time figuring out why I was having so much grief with that (it worked fine with the OpenGL RenderSystem).
Next, I plan on profiling the GL_RenderSystem to figure out those RTT issues, and upgrading to the newly released Ogre version 1.6.3!!
After getting my app running in DirectX, I used NVidia Perfhud to debug the framerate spikes - only to find that DirectX is vastly outperforming OpenGL! So now I can't really afford gDEBugger ($800), so I'm stuck with inserting my mini-profiler into the GL_RenderSystem code to figure out what parts are slowing down etc. That will be a good experience and help me get more familiar with Ogre RenderSystem calls.
Misc Notes:
- Make sure you play around with your RenderSystem configuration settings. I had set my Display Frequency to 59 and that caused the framerate to be cut in half. Dunno why I had it set to that value.
- With OpenGL you don't need the RenderSystem to issue _begin() and _end() frame calls, but you do in DirectX.
- Fixed a bug where when writing dynamic textures I was using pointer math and it was messing up my textures in DirectX. I switched to using array notation and it fixed the issue. Haven't spent much time figuring out why I was having so much grief with that (it worked fine with the OpenGL RenderSystem).
Next, I plan on profiling the GL_RenderSystem to figure out those RTT issues, and upgrading to the newly released Ogre version 1.6.3!!
Tuesday, July 21, 2009
Optimisation Fail
This is a maintenance/progress blog post so nothing exciting really. I just try to post a few times a month as any developer keeping a journal should.
I got rid of the vertex buffer and texture resource pools and created a mesh pool and each mesh has its' own vertex buffer and textures so the same thing is accomplished and the mesh resource manager is now way simpler. I used to have std::maps with pointers to the meshes in each list depending on what stage the mesh was in (needs building, built, and visible, cached and cache build) - now I have 3 std::vectors for 3 lists: needs building, built and visible.
The lists are stored in an array like this:
std::vector mMeshLists[3];
The built and visible lists are in index 0 and 1 and I swap them periodically like this:
mVisibleListIndex = (mBuiltListIndex + 1) % 2;
And the build list is always index 2.
Unfortunately, the app is still too jerky. Creating the textures on the graphics card is taking too long, generating the heightmaps is taking too long and it's not smooth even though I'm using threads for all the non-opengl stuff. Most of the time spikes are now happening in Ogre so I will probably have to add some profiling there to figure out what's going on.
Also, I switch over to DirectX 9 so that I can use NVidia's Perfhud tool to help me analyze how the graphics card and cpu are being utilized. That's been fun.
The only major bug I have at the moment is that the Render To Texture code that generates the terrain texture for each patch isn't working in DirectX right. My dynamic heightmap texture is not being created correctly and I don't know why yet. I have been experimenting with different pixel formats to no avail yet.
I'm almost thinking of doing another simpler version of the quad tree planet that uses geomippmapping and the planet size is restricted to 1025x1025 vertices per side - or maybe 2049x2049. This terrain is taking too much of my time to code that should be spent on other important game things!
I got rid of the vertex buffer and texture resource pools and created a mesh pool and each mesh has its' own vertex buffer and textures so the same thing is accomplished and the mesh resource manager is now way simpler. I used to have std::maps with pointers to the meshes in each list depending on what stage the mesh was in (needs building, built, and visible, cached and cache build) - now I have 3 std::vectors for 3 lists: needs building, built and visible.
The lists are stored in an array like this:
std::vector
The built and visible lists are in index 0 and 1 and I swap them periodically like this:
mVisibleListIndex = (mBuiltListIndex + 1) % 2;
And the build list is always index 2.
Unfortunately, the app is still too jerky. Creating the textures on the graphics card is taking too long, generating the heightmaps is taking too long and it's not smooth even though I'm using threads for all the non-opengl stuff. Most of the time spikes are now happening in Ogre so I will probably have to add some profiling there to figure out what's going on.
Also, I switch over to DirectX 9 so that I can use NVidia's Perfhud tool to help me analyze how the graphics card and cpu are being utilized. That's been fun.
The only major bug I have at the moment is that the Render To Texture code that generates the terrain texture for each patch isn't working in DirectX right. My dynamic heightmap texture is not being created correctly and I don't know why yet. I have been experimenting with different pixel formats to no avail yet.
I'm almost thinking of doing another simpler version of the quad tree planet that uses geomippmapping and the planet size is restricted to 1025x1025 vertices per side - or maybe 2049x2049. This terrain is taking too much of my time to code that should be spent on other important game things!
Subscribe to:
Posts (Atom)