Visual artifact, advice would be appreciated (beginner, D3D9)

Started by
9 comments, last by Noctumus 10 years, 5 months ago
Greetings, Forum!
I've recently begun studying Direct3D 9 but have unfortunately encountered a little bug in my latest experiment; a simple program that rotates a textured 6 pointed star figure about the 3 axes with a single directional light (source code available here). To describe the bug imagine I was rendering a ball instead of a star moving from the left side of the screen to the right. Then, this is what it looks like when the program runs normally (the top number being the frame in which the ball is rendered):
motion_normal.png
And this is what appears to be happening when the glitch occurs:
motion_glitch.png
I tried running the program without clearing the screen in each frame and managed to capture what it looks like when the glitch occurs with vsync enabled at 60 Hz (all three arrows point to visual artifacts caused by the same glitch):
glitch_screenshot.png
It appears what I thought was happening could actually be the case (especially if you look closely (click image to magnify) at what's going on near the left arrow). The problem is I don't have a clue what the heck is causing it. Taken into consideration I have less than a week's experience with Direct3D there's a good chance it's something very basic I'm missing that one of you can teach me about. At least I hope so, because right now it's driving me nuts blink.png
Here are some of the things I have gathered so far from testing and experimenting:
The glitch is apparently not caused by
  • A floating point rounding error
  • The performance counter returning a wrong value
The glitch is apparently not affected by whether
  • I use hardware or software vertex processing (D3DCREATE flags)
  • I use performance counters (QPF/QPC) or multimedia timers (timeGetTime) for calculating the delta time
  • I restrict the program to only run on a single CPU core or not
Some other observations:
  • The glitch appears, on average, about once every 10th second on my computer when vsync is enabled and about once every 3rd second when it's not (using D3DPRESENT_INTERVAL_IMMEDIATE in the present parameters to disable it)
  • The impact/magnitude of the glitch doesn't seem to be affected by whether vsync is enabled or not
  • The glitch appears very randomly; not at any specific angle or time and sometimes (much) less frequent than others (every now and then the program can run smoothly without any problems for several minutes)
I tried creating the device using D3DDEVTYPE_REF but this causes the framerate to drop so dramatically it's impossible for me to determine if the glitch still occurs. I also examined a couple of my Direct3D accelerated games to see if something similar could occur in one of them, but that didn't seem to be the case.
PS: If you want to compile and run the program you can download the texture here
Advertisement

Have you taken a log of your frame times to see what delta time there is when the glitch occurs? You might be able to gain some information there based on the statistics of how often the glitch occurs.

I have seen similar behavior before with my laptop, and the issue seemed to disappear when I built in release mode, but had the glitch in debug mode. I believe after a few driver updates the issue went away, but who knows if that is the same topic.

One point about your problem description - how do you know it is jumping ahead, then back, then forward again? It looks to me like you just end up with one frame taking longer than the others, so there is larger movement due to your animation having more time to move. Is there something that I'm not understanding here?

Have you taken a log of your frame times to see what delta time there is when the glitch occurs? You might be able to gain some information there based on the statistics of how often the glitch occurs.

I made a version that deliberately generated glitches in order to determine how big the delta time would have to be in order to cause these visual artifacts. Then I added functionality to keep track of the minimum, maximum, and average values and tried capping the dt to ensure it would always lie close to the average (+/- 20%). This, however, didn't solve the problem. Even when the dt couldn't possibly be anywhere near the value required to generate these huge gaps the glitches still occurred. This is also one of the things that made me think it's probably something related to D3D that's causing it (like some buffer not being flushed or whatever). I haven't tried logging the times though, but even if I did I'm not sure it would even help me figure out what's causing the problem.

One point about your problem description - how do you know it is jumping ahead, then back, then forward again? It looks to me like you just end up with one frame taking longer than the others, so there is larger movement due to your animation having more time to move. Is there something that I'm not understanding here?

I don't know if this ping-pong pattern is what's actually happening; it's just how I perceive it when the program is running and since a single frame only lasts around 16 ms at 60 Hz I could very well be wrong. In fact I actually think your own theory is much more plausible, but even so I don't know what to do about it. I mean it's a pretty simple program and without more knowledge about D3D it feels like there's not a whole lot of things left to try :/

Thanks for your feedback.

Are you running your latest possible drivers, and executing the release build outside of the IDE?

Open up the DirectX control panel, go into the Direct3D 9 tab, and switch over to the Debug version of the Direct3D 9 runtime. Also turn up the "output level" to one notch left of the "more" side (all the way to the "more" side spams out too many useless warnings).

Then when your game is running, watch the output window to see if any interesting errors are logged.

Also, watch the screen to see if it ever flickers green or pink -- this is an indication that you've called Present without actually drawing anything first. With the debug runtime, you'll get a pink/green screen when doing this, but in the normal mode, you'll get undefined results, which includes seeing the previous frame repeated (which could explain your one-frame backwards jitter).

I highly doubt there is a glitch at all, especially not a ping-pong glitch.

It appears to be just skipping a frame, which could be due to any number of natural causes.

  1. A missed v-blank, even slightly, will cause you to move on to the next frame and a later position, since you are using QueryPerformanceCounter().
  2. Any form of exterior lag can build up to cause a skip such as that.
    • It happens every 10 seconds with v-sync and 3 without. That indicates that there is likely a memory buffer or similar that is building up each frame and then flushing once it gets too large, causing the lag. At a faster framerate it builds up faster and flushes more frequently.
    • This could be related to printf() or std::cout if you are printing debug information frequently.
    • Or it could be any number of memory mismanagement issues that cause the operating system to purge pages etc.
    • As Jason Z mentioned, even running in the debugger in the IDE can cause this kind of jitter, so always run in release mode outside of the IDE.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


This could be related to printf() or std::cout if you are printing debug information frequently.

This is a good lead - any type of logging could lead to semi-periodic jitters in framerate as the file buffer is purged.

Are you running your latest possible drivers, and executing the release build outside of the IDE?

I appreciate your feedback but I just updated my driver less than a week ago and all tests were executed outside the IDE.

Open up the DirectX control panel, go into the Direct3D 9 tab, and switch over to the Debug version of the Direct3D 9 runtime. Also turn up the "output level" to one notch left of the "more" side (all the way to the "more" side spams out too many useless warnings).

Then when your game is running, watch the output window to see if any interesting errors are logged.

Also, watch the screen to see if it ever flickers green or pink -- this is an indication that you've called Present without actually drawing anything first. With the debug runtime, you'll get a pink/green screen when doing this, but in the normal mode, you'll get undefined results, which includes seeing the previous frame repeated (which could explain your one-frame backwards jitter).

Thanks for enlightening me about the DirectX Control Panel wink.png I tried creating an IDE project and did what you instructed which actually resulted in a couple of warnings from the DX environment. However, after having adjusted the code accordingly the glitches still occurred and the screen didn't turn pink/green at any point (unfortunately since what you described about seeing the previous frame repeated could definitely have been what was happening).

The good news is I think I may have found a way to figure out what's causing the trouble since the program is heavily based on one of the tutorials that ship with the DirectX SDK which, despite the similarity, does not have the same problem as my own program. What I'll do is simply use the tutorial as a starting point and try to "morph" it into my own program gradually and see when the glitches start appearing. I'll let you know if I find it.

Quite frequently the difference is in the inconspicuous debug output you add to your own projects…

And now that you have not seen green or pink it should be very obvious this is not really a glitch, but rather just a missed frame.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid


[quote name ='Jason Z']
Are you running your latest possible drivers, and executing the release build outside of the IDE?

[/quote]
I appreciate your feedback but I just updated my driver less than a week ago and all tests were executed outside the IDE.

Sorry, I don't mean to beat a dead horse, and I'm not trying to pick at details, but did you mention that you were running the release build? I have seen a very similar thing in the past that only occurs in the debug build, so I want to make sure you aren't seeing the same issue.

Also, just out of curiosity, can you describe your hardware and OS? Is the same behavior seen on a different system, or is the issue isolated to your machine?

This topic is closed to new replies.

Advertisement