Sign in to follow this  
SmoothRide

Directx performance and QueryPerformanceCounter issues

Recommended Posts

I have a couple of puzzling issues. I have some code that I put together a while back which is basically a shell for creating games. It creates a winapi window, initializes directx objects and runs a game loop, which in turn contains high precision timer to calculate rate of movement and cap framerates. I am using "C++", directx 9, and Visual Studio 2005 by the way. Now I know that this code worked back when I first wrote it, but I was using another computer. It was a P4 while now I have a Core 2 Quad. I have recently recompiled this code and now I am seeing at least two strange things: 1. My first issue may be trivial, but I don't understand why it's happening. Basically my directx call throttles down the performance of my application to exactly 60 iterations per second. But when I comment out the call to directx render then the loop runs several thousand times in one second, as it should when not capped. At this point I am hardly rendering anything, just displaying a white background with framerate number on it. It displays fine, but why does it slow down the app so much. Is it some kind of parameter within directx that limits the framerate? If it is, then why does it slow down the whole program instead of just displaying at most 60 times per second. Anyway, just in case, here's my bare-bones directx rendering logic: hardware->GetDXDevice()->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 1.0f, 0); hardware->GetDXDevice()->BeginScene(); _itoa_s(in_frame_counter, str, 10); rectangle.top = 0; rectangle.left = 0; rectangle.right = 200; rectangle.bottom = 40; hardware->GetDXFont()->DrawText(NULL, str, -1, &rectangle, DT_CENTER | DT_VCENTER, 0xffff0000); _itoa_s(in_frames_realtime, str2, 10); rectangle.top = 0; rectangle.left = 200; rectangle.right = 400; rectangle.bottom = 40; hardware->GetDXFont()->DrawText(NULL, str2, -1, &rectangle, DT_CENTER | DT_VCENTER, 0xffff0000); hardware->GetDXDevice()->EndScene(); hardware->GetDXDevice()->Present(NULL, NULL, NULL, NULL); 2. My high precision timer looks haywire although ultimately it appears to work. Calling QueryPerformanceFrequency returns something nonsensical like -1894907296. A set of QueryPerformanceCounter results done 60 times per second looks like this: Current Move time: 1207363689 Current Move time: 1225982997 Current Move time: 1233711990 Current Move time: 1241115012 Current Move time: 1243310976 Current Move time: 1244989962 Current Move time: 1245095172 Current Move time: 1245143061 Current Move time: 1245683349 Current Move time: 1275026004 Current Move time: 1308568734 Current Move time: 1348646346 Current Move time: 1388618631 Current Move time: 1428733620 Current Move time: 1468780632 Current Move time: 1508746383 Current Move time: 1548848169 Current Move time: 1588846437 Current Move time: 1628923221 Current Move time: 1668881178 Current Move time: 1708847199 Current Move time: 1748741733 Current Move time: 1788777819 Current Move time: 1828973700 Current Move time: 1869027507 Current Move time: 1909026846 Current Move time: 1949106672 Current Move time: 1989100422 Current Move time: 2029078539 Current Move time: 2069191692 Current Move time: 2109182301 Current Move time: -2145731665 Current Move time: -2105910922 Current Move time: -2065677079 Current Move time: -2025576967 Current Move time: -1985545039 Current Move time: -1945497712 Current Move time: -1905580075 Current Move time: -1865515783 Current Move time: -1824524698 Current Move time: -1784276725 Current Move time: -1745609530 Current Move time: -1705372726 Current Move time: -1665397858 Current Move time: -1625282653 Current Move time: -1585169527 Current Move time: -1545184480 Current Move time: -1505192062 Current Move time: -1465204108 Current Move time: -1425126847 Current Move time: -1385137219 Current Move time: -1345001314 Current Move time: -1303128130 Current Move time: -1265090359 Current Move time: -1224992524 Current Move time: -1185192175 Current Move time: -1145006113 Current Move time: -1105032055 Current Move time: -1064681779 Current Move time: -1024804579 Current Move time: -985012177 Current Move time: -944788045 Current Move time: -904730755 I don't understand why the numbers go from positive to negative then back to positive and so forth. I created a small console application to test out the QPC timer and it actualy produces "normal" results: Start Value: {0} 232510385316024 End Value: {0} 232510385318256 QueryPerformanceCounter minimum resolution: 1/{0} Seconds. 2400060000 100 Increment time: {0} seconds. 9.29977e-007 QPC: 232510401985293 QPC: 232510403762181 QPC: 232510405584672 QPC: 232510407426909 QPC: 232510409305011 QPC: 232510411136493 QPC: 232510413023775 QPC: 232510414895037 QPC: 232510416714918 QPC: 232510418513811 QPC: 232510420313694 QPC: 232510422133665 QPC: 232510423950072 QPC: 232510425810417 QPC: 232510427659080 QPC: 232510430179062 QPC: 232510432606650 QPC: 232510434446502 QPC: 232510436246475 QPC: 232510438176552 QPC: 232510440011274 QPC: 232510441867056 QPC: 232510443854850 QPC: 232510445797410 QPC: 232510447687698 QPC: 232510449565881 QPC: 232510451613804 QPC: 232510453480701 QPC: 232510455435690 QPC: 232510457336463 QPC: 232510459294296 QPC: 232510461247701 QPC: 232510463416656 QPC: 232510465924758 QPC: 232510468356504 QPC: 232510470917355 QPC: 232510472848323 QPC: 232510474800540 QPC: 232510476780171 QPC: 232510478805720 QPC: 232510480728156 QPC: 232510482642465 QPC: 232510484554029 QPC: 232510486457835 QPC: 232510488417450 QPC: 232510490509464 QPC: 232510492454904 QPC: 232510494390732 QPC: 232510496470326 QPC: 232510498373106 QPC: 232510500283086 QPC: 232510502140776 QPC: 232510504095720 QPC: 232510505998977 QPC: 232510507945029 QPC: 232510509880074 QPC: 232510511769633 QPC: 232510513720086 QPC: 232510515557760 QPC: 232510517489232 Ultimately the timer works because I have a counter that keeps track of how many times the code for game logic gets executed and when I set the rate to be (QPF frequency / 250), it does get triggered exactly 250 times before 1 second elapses and the counter is reset. Any ideas for the strange looking numbers? I am using __int64 data type for all my timer variable, the same way as in the test program so I am lost as to why there's a difference. Any help on either of these issues (especially the first) is much appreciated!

Share this post


Link to post
Share on other sites
When you created the D3D device, you set something called a presentation interval. Ensure that's set to immediate, otherwise the call to Present() will wait for the monitor to refresh.

Edit: It's part of the presentation parameters. PresentationInterval needs to be set to D3DPRESENT_INTERVAL_IMMEDIATE.

Share this post


Link to post
Share on other sites
Quote:
Original post by gekko
When you created the D3D device, you set something called a presentation interval. Ensure that's set to immediate, otherwise the call to Present() will wait for the monitor to refresh.

Edit: It's part of the presentation parameters. PresentationInterval needs to be set to D3DPRESENT_INTERVAL_IMMEDIATE.


Indeed that solved issue #1. Thanks!

One down, one to go...

Share this post


Link to post
Share on other sites
Quote:

Current Move time: 1207363689


That looks like to me like you're only displaying 32-bits of the value returned from QueryPerformanceCounter. It returns a LARGE_INTEGER which is 64-bit, you have to use the whole 64-bits.

Share this post


Link to post
Share on other sites
[edit] I typed all this stuff... and realized that I didn't read your initial post very well... sorry.[/edit]

Soo now that I have read it properly (sorry again), the reason your numbers wrap like 32 bit numbers is because _itoa_s uses 32 bit inputs. So even though you pass a 64 bit number, it gets implicitly casted to 32 bits. Thus it wraps at the 32 bit boundary. Try _i64toa_s instead, and you should be good to go.

Cheers
-Scott

Share this post


Link to post
Share on other sites
Quote:
Original post by popsoftheyear
[edit] I typed all this stuff... and realized that I didn't read your initial post very well... sorry.[/edit]

Soo now that I have read it properly (sorry again), the reason your numbers wrap like 32 bit numbers is because _itoa_s uses 32 bit inputs. So even though you pass a 64 bit number, it gets implicitly casted to 32 bits. Thus it wraps at the 32 bit boundary. Try _i64toa_s instead, and you should be good to go.

Cheers
-Scott


I got it. Somewhat predictably it turns out that I am retarded.

All of you guys were essentially correct that data is getting truncated. My program worked correctly because the variables are fine. However I was writing the timer values to a file with fprintf and I used %d specifier with my __int64 so it was just getting cut off during output. I changed it to %lld and it works fine. Duh!

Thanks for suggestions everyone.

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