Sign in to follow this  
Plerion

[XNA] Strnage behaviour on 3D

Recommended Posts

Plerion    381
Hello! After i learned enough about UI in XNA (i come from unmanaged DirectX) i ported some of my unmanaged directX code for 3d models to XNA. I use the following to render:
        public void Render()
        {
            Game1.Instance.GraphicsDevice.RenderState.CullMode = CullMode.None;
            modelLock.WaitOne();
            _3dEffect.Begin();
            foreach (EffectPass pass in _3dEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                foreach (ADTFile f in files)
                    f.Render();
                pass.End();
            }
            _3dEffect.End();
            modelLock.ReleaseMutex();
        }

whereas ADTFile::Render calls just ADTChunk::Render for all 256 chunks, which does the following:
        public void Render()
        {
            Game1.Instance.GraphicsDevice.VertexDeclaration = vDeclaration;
            Game1.Instance.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
                vertices, 0, 145, iBuffer, 0, 256);
        }

So i have a problem with that. The whole system seems to get slow (hovering an item on the desktop takes some seconds until the hover-border appears, gloweffects in the system menu of every window the same). If i look at the taskmgr my application uses 50 mb RAM and 6% CPU. Whats the reason for that? I mean 256 * 256 triangles shouldnt be a big deal or am i wrong? Greetings Plerion

Share this post


Link to post
Share on other sites
Plerion    381
I just user XNA's default, it creates its own device.

The strange thing is that measuring the time within the full Game.Draw method (which is the place where XNA requests drawing calls) it takes 9-15 milliseconds. But even then every graphic feature in the system begins to lag (Flashes, Highlights, Glows, ...) but the rest works good (browsing folders, refreshing internet). If i remove the DrawIndexedPrimitive from the code all is good.

Share this post


Link to post
Share on other sites
remigius    1172

I'm afraid I can only offer a bit of guessing, but maybe it helps. First of all taskmgr reportedly isn't quite the best tool to make these assessments and I've often seen the advice to use resmon instead. Next up .NET tends to be a bit more liberal with how it reserves space for processes, so as long as you don't see a steady increase in memory usage you shouldn't get too concerned about it just yet.

Getting to the 6% processor usage, that doesn't seem too bad. I obviously don't know what your code is doing exactly, or how much better the C++ version is doing, but as an overgeneralized blanket statement, 6% usage sounds fair enough for 256 draw calls. Draw calls take processor usage (more info here) and considering the old rule of thumb (so outdated and unreliable!) for SM2 hardware was that about 750 draw calls should be your upper bound, it's doing pretty well.

As for the system getting slow, I doubt it has anything to do with the overall performance characteristics of your program, since the memory & processor usage shouldn't be taxing your system. Have you tried running the app with the DirectX debug runtimes to see if anything is going wrong under the hood? If so, that might be an explaination why the system graphics are acting up. Edit - I only just now considered your locks & mutexes... You aren't using multiple threads to access your device-bound resources are you? I always found that to be just asking for trouble but YMMV [smile]

Share this post


Link to post
Share on other sites
Plerion    381
Hey!

What do you mean with device-bound ressources? I do all drawing calls in the same thread. The model files tet all loaded in the same thread. But the UI textures get loaded from different threads.

I will have a look with the debug runtime.

Share this post


Link to post
Share on other sites
kociolek    122
I'm see 2 possibilities:
1) Game1.Instance.GraphicsDevice.VertexDeclaration = vDeclaration;
try set this only once and change if need

2) What exacly does modelLock.WaitOne() ?

Share this post


Link to post
Share on other sites
Plerion    381
1. No this changes nothing
2. Its just a mutex being acquired. I also removed that as its not yet needed as there are no other threads acting with the ModelMgr yet and it didnt change.

Share this post


Link to post
Share on other sites
remigius    1172

Quote:
Original post by Plerion
But the UI textures get loaded from different threads.


This *might* be causing the problem, or at least adding to it. I haven't messed with multithreading XNA myself, but in its predecessor Managed DirectX accessing the device (that includes loading textures onto it) from multiple threads was quite the can of worms. You could make the device multithreading-enabled with a flag that made device accesses critical sections (like in normal DX9 afaik) but it typically didn't work out too well. I trust the thread access exclusions worked, but I got my share of blue screens where the driver/hardware just didn't like being used by multiple threads.

I don't know if the aforementioned flag is set onto XNA devices or if they have some other means of trying to be thread-safe, but the general advice seems to be to avoid accessing/creating/disposing device-bound resources (textures, meshes, RTs etc) from other threads than the main thread running your game loop. You can still use other threads to load data or operate on a CPU copy of your vertices or textures, but the actual calls to Load/Set/GetData are safest left to the main thread.

Again to be sure, I'm just guessing so don't go throwing your code overboard just on my hunch. If you have the option to load the UI textures from your main thread though, I'd try that to see if it solves your problem. Checking out the debug runtimes however should indeed be the first stop [smile]

Share this post


Link to post
Share on other sites
EJH    315
It could be that DrawUserIndexedPrimitives() is slower than DrawIndexedPrimitives(). There is a discussion here explaining the difference:

http://forums.xna.com/forums/p/5136/26941.aspx#26941

If the mesh only rarely or never changes you should put it in a vertex buffer and use DrawPrimitives.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this