Jump to content

  • Log In with Google      Sign In   
  • Create Account


[DX9] Vsync Lag


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 Armion   Members   -  Reputation: 272

Like
0Likes
Like

Posted 19 August 2010 - 08:47 AM

Hi guys,

Before i get to the question i need to clarify some things. I'm a novice so don't be too harsh on me if i make some stupid mistake :) Also English is not my native language :)

I spent the last two days trying to understand the extreme input lag(or at least i thought so at first) i get when using vsync (D3DPRESENT_INTERVAL_DEFAULT or D3DPRESENT_INTERVAL_ONE) or when having low fps(in the case below 240fps) in my simple 3d application. I read a lot of articles and posts in different forums and reached a conclusion that it's kind of normal because the specifics or vsync and buffering. Still i'm not sure that that much lag is normal. To be more precise it's not exactly input lag - more like something to do with presentation lag. I'm reading the book of Frank Luna about DirectX 9.0, so i modified the source of chapter one to show you what i mean. It's pretty basic stuff, but is perfect for demonstration. The idea is simple - you move the mouse around the window and a mouse texture is drawn at the current position of the mouse every frame... The two cursors should overlap perfectly... Or at least i want it to be that way, but it isn't. The DirectX drawn mouse always lags behind the Windows cursor and it's quite annoying for me. One more important thing - i'm using Windows 7 and disabling Aero almost fixes the problem. I don't have a Windows XP PC to test there. I was planning on doing a simple DirectX GUI Library to use in my future education projects, but when i came across this problem i just wonder what will dragging look like... I remember seeing some commercial games behave the same way with vsync enabled - can't recall any names at the moment. Still, the majority of them don't behave that way. I just don't believe that you have to render at least 240 frames for smooth feeling even if you don't have vsync enabled.

To be honest i tried some solutions, but none of them gave me satisfactory results except disabling Aero - but i don't think that's the solution(I'm still interested why is that working at all). I also tried decreasing render ahead and even disabling it completely - still no improvement. I'm posting the source as i don't see an option for attaching files.



FILENAME: d3dUtility.h
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: d3dUtility.h
//
// Author: Frank Luna © All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Provides utility functions for simplifying common tasks.
//
//////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __d3dUtilityH__
#define __d3dUtilityH__

#include <d3dx9.h>
#include <string>

namespace d3d
{
bool InitD3D(
HINSTANCE hInstance, // [in] Application instance.
int width, int height, // [in] Backbuffer dimensions.
bool windowed, // [in] Windowed (true)or full screen (false).
D3DDEVTYPE deviceType, // [in] HAL or REF
IDirect3DDevice9** device);// [out]The created device.

int EnterMsgLoop(
bool (*ptr_display)(float timeDelta));

LRESULT CALLBACK WndProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);

static HWND handle;

HWND GetHandle();

template<class T> void Release(T t)
{
if( t )
{
t->Release();
t = 0;
}
}

template<class T> void Delete(T t)
{
if( t )
{
delete t;
t = 0;
}
}
}

#endif // __d3dUtilityH__




FILENAME: d3dUtility.cpp
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: d3dUtility.cpp
//
// Author: Frank Luna © All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Provides utility functions for simplifying common tasks.
//
//////////////////////////////////////////////////////////////////////////////////////////////////

#include "d3dUtility.h"

bool d3d::InitD3D(
HINSTANCE hInstance,
int width, int height,
bool windowed,
D3DDEVTYPE deviceType,
IDirect3DDevice9** device)
{
//
// Create the main application window.
//

WNDCLASS wc;

wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)d3d::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = "Direct3D9App";

if( !RegisterClass(&wc) )
{
::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
return false;
}

HWND hwnd = 0;

DWORD styles = WS_CAPTION | WS_SYSMENU | WS_EX_TRANSPARENT;
RECT screenRect = {300, 300, 300 + width, 300 + height};
AdjustWindowRect(&screenRect, styles, false);

hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App",
WS_CAPTION | WS_SYSMENU | WS_EX_TRANSPARENT,
screenRect.left, screenRect.top, screenRect.right - screenRect.left, screenRect.bottom - screenRect.top,
0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);

if( !hwnd )
{
::MessageBox(0, "CreateWindow() - FAILED", 0, 0);
return false;
}

handle = hwnd;

::ShowWindow(hwnd, SW_SHOW);
::UpdateWindow(hwnd);

//
// Init D3D:
//

HRESULT hr = 0;

// Step 1: Create the IDirect3D9 object.

IDirect3D9* d3d9 = 0;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

if( !d3d9 )
{
::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
return false;
}

// Step 2: Check for hardware vp.

D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

int vp = 0;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

// Step 3: Fill out the D3DPRESENT_PARAMETERS structure.

D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

// Step 4: Create the device.

hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, // primary adapter
deviceType, // device type
hwnd, // window associated with device
vp, // vertex processing
&d3dpp, // present parameters
device); // return created device

if( FAILED(hr) )
{
// try again using a 16-bit depth buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
device);

if( FAILED(hr) )
{
d3d9->Release(); // done with d3d9 object
::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
return false;
}
}

d3d9->Release(); // done with d3d9 object

return true;
}

HWND d3d::GetHandle()
{
return handle;
}

int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime);
ptr_display(timeDelta);

lastTime = currTime;
}
}
return msg.wParam;
}




FILENAME: d3dinit.cpp
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: d3dinit.cpp
//
// Author: Frank Luna © All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Demonstrates how to initialize Direct3D, how to use the book's framework
// functions, and how to clear the screen to black. Note that the Direct3D
// initialization code is in the d3dUtility.h/.cpp files.
//
//////////////////////////////////////////////////////////////////////////////////////////////////

#include "d3dUtility.h"

//
// Globals
//

IDirect3DDevice9* Device = 0;
LPDIRECT3DTEXTURE9 texture = 0;
LPD3DXSPRITE sprite = 0;

//
// Framework Functions
//

bool Setup()
{
// Nothing to setup in this sample.

HRESULT r1 = D3DXCreateTextureFromFile(Device, "C:\\Users\\Armion\\Desktop\\cursor.png", &texture);

HRESULT r2 = D3DXCreateSprite(Device, &sprite);

return true;
}

void Cleanup()
{
// Nothing to cleanup in this sample.
texture->Release();
sprite->Release();
}

bool Display(float timeDelta)
{
if( Device ) // Only use Device methods if we have a valid device.
{
// Instruct the device to set each pixel on the back buffer black -
// D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on
// the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.

static float totalTime = 0;
static int frames = 0;
totalTime += timeDelta;
frames++;

HWND handle = d3d::GetHandle();

if (totalTime > 1000)
{
char strFrames[10];
itoa(frames, strFrames, 10);
char strFps[16];
strcpy(strFps, "FPS: ");
strcat(strFps, strFrames);

frames = 0;
totalTime -= 1000;
::SetWindowTextA(handle, strFps);
}


Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
Device->BeginScene();


POINT coords;
::GetCursorPos(&coords);
::ScreenToClient(handle, &coords);

RECT client;
GetClientRect(handle, &client);

D3DXVECTOR3 pos(coords.x, coords.y, 0);

sprite->Begin(D3DXSPRITE_ALPHABLEND);
HRESULT test = sprite->Draw(texture, 0, 0, &pos, 0xFFFFFFFF);
sprite->End();

//::SetWindowText(hwnd,

Device->EndScene();


// Swap the back and front buffers.
Device->Present(0, 0, 0, 0);
}
return true;
}

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
::PostQuitMessage(0);
break;

case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
640, 480, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(0, "InitD3D() - FAILED", 0, 0);
return 0;
}

if(!Setup())
{
::MessageBox(0, "Setup() - FAILED", 0, 0);
return 0;
}

d3d::EnterMsgLoop( Display );

Cleanup();

Device->Release();

return 0;
}



Thanks in advance :)

Sponsor:

#2 unbird   Crossbones+   -  Reputation: 4786

Like
0Likes
Like

Posted 19 August 2010 - 09:30 AM

Welcome to the forum.

And actually you're behaving perfectly fine for a first poster IMHO: Proper explanation of your problem, what you have tried sofar, code tags... [smile]

Short answer: I think you experience normal behaviour. The "lag" happens because the actual drawing - when windows blits your backbuffer - will always be slightly later than your input grabbing. Haven't used Windows 7 and Aero, my guess is just that in such a setup you will get an intermediate blit because of the effects used. So yes: It's a "presentation lag".

See also
Lag free input
[XNA, mouse lag]
Mouse lag under DirectX9

Hope that helps

unbird

#3 Demirug   Members   -  Reputation: 884

Like
0Likes
Like

Posted 19 August 2010 - 09:36 AM

That’s the expected behavior. The reason for this is that the windows mouse cursor is applied when the image is transferred from the front buffer to the display. Your rendered mouse cursor is applied when you send the command to the API. If your CPU is faster than your GPU (it should in your V-Sync case) Direct3D will cache up to 3 frames in the command queue. This and another one in process gives you 4 frames. With 60Hz this would be ~67 ms. As Aero uses Direct3D too it will add some more time. This will only happen in window mode as Aero disable itself when you switch to fullscreen.

Because of this it is not recommend to use an own cursor and the hardware cursor at the same time. If you need a cursor use the hardware cursor.


#4 Armion   Members   -  Reputation: 272

Like
0Likes
Like

Posted 19 August 2010 - 10:27 AM

Thanks for the answers, guys :) I used the two cursors to show exactly what i mean by this lag. I don't plan on counting on them both in the future.

If there was some input i guess it's alright, but in this case there isn't any. The application is not using windows messages like WM_MOUSEMOVE. It's only polling the cursor position and it's right before i call Draw on the Sprite object. I know that doesn't mean that the image of the cursor is drawn exactly at that moment i call Draw() - as far as i understand the command is queued for later drawing. But how much time can really pass between Draw() and actual drawing? Shouldn't the frame be ready by the time Present() returns? As far as i remember Present() takes a lot of time to complete in this case - actually it takes so much because it's waiting for the next vertical retrace period. So in the case of 60Hz refresh rate should the difference in time between Draw() and Present() be strictly less than 16.66ms? Maybe the buffering has something to do with it... Aren't we drawing to the back buffer and flipping them on Present()? Doesn't that mean that there should be no more than 1/60 second lag? And is 1/60 lag even noticeable? Is there a realistic way to measure how much time is lost in between doing something and seeing it on the screen?

Can someone explain a bit more about DirectX caching frames on the commands buffer? How come it caches more than 60 frames when i only call Present() 60 times per second. How can it decide on its own to render more frames? Where does it get the data and commands for rendering from? Isn't this behavior connected the render-ahead, that i disabled through the NVidia Control Panel and RivaTuner? What does CPU is faster than the GPU means in my case? I'm NOT using multi-threading - isn't the CPU just waiting for Present() in this case?

And some more questions... I hope someone has the time and is willing to answer them :D

How are commercial games dealing with this problem? I don't remember there being any lag when i'm dragging items in my inventory when playing a random RPG or aiming headshots in some shooter. That said it's true that the Windows' cursor is not shown in the game and this certainly help maintain the illusion of smoothness and lagness(i'm not sure such word even exists...) And, as i mentioned, i don't think commercial, graphics-exacting games render a lot of frames(let's say 200-250)and still don't have this problem in such a severe case. Please note that i know it's just natural that they lag a bit, but it's not obvious for me... Even when only getting 40 fps for example... And the lag in my simple app is just making me... Let's say i don't like it at all :D

If Aero is slowing my application down in windowed mode, why is it lagging more in fullscreen than in windowed with Aero disabled? I guess i forgot to put that fact in the previous post.

And now to read the articles... Thanks again, guys :)

[Edited by - Armion on August 21, 2010 4:27:22 AM]

#5 Armion   Members   -  Reputation: 272

Like
0Likes
Like

Posted 20 August 2010 - 07:00 AM

I read the articles unbird mentioned but still can't find an answer to my questions... I hope it's not a bad practice bumping your own thread up again :)

Edit: Changed "your thread" to "your own thread" :)

[Edited by - Armion on August 20, 2010 1:00:59 PM]

#6 unbird   Crossbones+   -  Reputation: 4786

Like
0Likes
Like

Posted 20 August 2010 - 07:47 AM

Actually it's your thread, and I admit, it was a bit a blind shot: just did a forum search and took the most appropriate ones. And I thought Demirug has made it clear that you can't avoid a lag at all, only "improve" it with a hardware cursor. Is it really that bad in your case ?

Can't help you further. Lower level details of DirectX elude me, let alone Windows 7 specifics (I use XP).

#7 Scoob Droolins   Members   -  Reputation: 238

Like
0Likes
Like

Posted 20 August 2010 - 02:44 PM

Input lag is a big, but unavoidable problem for most games, particularly high speed racing sims like ours (rFactor). In the best case, you'll always have at least one frame of lag. The causes are:

- buffering of commands by the DX runtime - you can minimize this somewhat by setting the 'render frames ahead' value to 1 on nVidia; there is a way to do this on ATI, but it requires a 3rd party utility like ATI Tool. Command queue buffering is designed to increase apparent frame rate at the expense of lag, mostly for benchmarking purposes.

- triple buffering, which keeps the GPU busy but adds an extra frame of lag.

- multi-GPU setups like SLI and XFire, when running in AFR-type modes. The recommended command queue buffering is 1 per GPU. Apparently massive rendering speed makes up for the lag.

- LCD monitors introduce their own lag because they buffer the upcoming display frame for scaling, but you can minimize this by setting your monitor to 1:1 pixel scaling if available, this may bypass the monitor's scaling hardware.

You can try vsync or other waiting methods to limit the commands sent to the GPU, but if your game internals need to run faster than the monitor refresh rate (as our does), the you'll have to do some threading to allow different processing to run at independent rates.

One harsh way to minimize lag is to use an event query around each frame, which actually stalls the pipeline until the current commands in the queue are processed. This is not recommended by Microsoft as it breaks concurrency, but if your game can render frames at the display's refresh rate or higher, you probably won't notice any slowdowns.

#8 Matias Goldberg   Crossbones+   -  Reputation: 3000

Like
0Likes
Like

Posted 20 August 2010 - 03:47 PM

Ok, I shall add two comments:

* In windowed mode with Aero enabled there is a layer of 3D surfaces that is added, which makes it slower (and "laggier")

* In Windows Vista/7 (specially 7) if a single parameter that sets your application to fullscreen is wrong (have fun figuring out which one is it) Win 7 will revert to "copy blit" rather than "flip" surface, which is slower and laggy.

This is specially true for DX10/11 but may occasionally happen in DX9.
I advise you to go to the latest DX SDK's samples and see exactly how they manage switching to fullscreen with their utility library.

That being said, it can be just that when you're low on fps, it just becomes laggy. It's a common problem. If you can't use hardware functions, try using at least a different thread for polling mouse position.

Quote:
I'm now using multi-threading - isn't the CPU just waiting for Present() in this case

Only the rendering thread (the one calling present) will wait for Present().
For the other threads you'll need a way to make them wait.
If the thread is a lazy thread (i.e. only polls mouse cursor every now and then) put it to Sleep(ms)
If the thread makes intensive stuff, performance critical (i.e. processes the main logic update) you'll need a live spin lock to make it wait. For more information about that one, see fix your timestep

Cheers
Dark Sylinc

#9 Hazard_X   Members   -  Reputation: 118

Like
0Likes
Like

Posted 20 August 2010 - 07:43 PM

Check whether the current device supports Hardware Cursors (almost all graphics cards do) and just use the windows cursor in your app. You can also assign a custom image to it to make it fit into your environment. Just make sure that cursor images are 32x32 pixel in size, or you might get flickering on some graphics cards.

This will give you perfectly smooth results. It doesn't matter how laggy the rest of the UI is. It will feel fine as long as the cursor is lag-free.

#10 Armion   Members   -  Reputation: 272

Like
0Likes
Like

Posted 20 August 2010 - 10:22 PM

Hi again and thanks for the replies :)

@Scoob Droolins: One frame of lag is acceptable. The problem in the case is that there is much more delay(in my opinion). I tried the query method and the result was the same. Playing with "render frames ahead"... no improvement i can feel.

@Matias Goldberg: Hmm... I will test if there is any error in my arguments when creating the fullscreen. Could this be related to the Ex version of interfaces and calls(IDirect3DDevice9Ex, PresentEx())? I don't think low fps is the problem - getting more than 4000 with D3DPRESENT_INTERVAL_IMMEDIATE - my app is just rendering its own cursor below the real one. I also tried one solution that was rumored to fix this lag in commercial games(Unreal Tournament, Battlefield 2 Bad Company) - limiting your fps to one or two below the refresh rate - let's say 58fps for 60Hz refresh rate... And it works like a charm. Can someone explain to me this STRANGE behavior? I also read there was some kind of bug in Win7 that was related to the difference between the actual refresh rate and the one that the OS reports to apps. I think i need to find a WinXP PC so i can test if things work the same way... Also i mistake on my part - i wanted to write "NOT USING MULTITHREADING", instead i wrote "now using multithreading" and this changes the thing a lot. I'm sorry for this silly mistake on my part.

@Hazard_X: Dragging something in the interface with this method produces very unsatisfactory results. It's like the object i'm dragging is tied to the cursor with some kind of rubber leash - always lagging behind a lot. I know that this is true even when dragging something in windows, selecting text in Firefox or text editor or selecting multiple icons on the desktop with selection rectangle, but it certainly is MUCH LESS laggy than the simple app i wrote to demonstrate the problem...

[Edited by - Armion on August 21, 2010 4:22:32 AM]

#11 Matias Goldberg   Crossbones+   -  Reputation: 3000

Like
0Likes
Like

Posted 21 August 2010 - 06:58 AM

Quote:
Original post by Armion
@Matias Goldberg: Hmm... I will test if there is any error in my arguments when creating the fullscreen. Could this be related to the Ex version of interfaces and calls(IDirect3DDevice9Ex, PresentEx())?

I don't think so.
The problem is basically when the device doesn't like the arguments for the backbuffer format you passed for the actual resolution you end up using (i.e. wrong refresh rate or bpp colour).

Quote:
Original post by Armion
I don't think low fps is the problem - getting more than 4000 with D3DPRESENT_INTERVAL_IMMEDIATE - my app is just rendering its own cursor below the real one.(Unreal Tournament, Battlefield 2 Bad Company)

Oh I see, I thought this problem appeared when you were low on fps with VSync enabled.

Quote:
Original post by Armion
- limiting your fps to one or two below the refresh rate - let's say 58fps for 60Hz refresh rate... And it works like a charm. Can someone explain to me this STRANGE behavior?

Well, I'm not sure if I get what exactly you're doing, but seems you're clamping the FPS through the CPU. I can only guess with +60fps present() takes time inside the driver, while having 58-59fps makes present() returns almost immediately except for occasional nano- or milliseconds delay to synchronize with the monitor's refresh; which makes your timing response somehow more accurate. I'm only guessing

There's something I don't understand though about how you're rendering the cursor.
If I understand correctly, you're letting the window's default cursor to show on top of the in window, and at the same time you're drawing a quad with your own cursor. Then use a function like GetCursorPos() to draw it in the same position the hardware cursor should be?
How exactly are you doing this?

#12 Armion   Members   -  Reputation: 272

Like
0Likes
Like

Posted 21 August 2010 - 08:49 AM

Hi Matias :)

As you can see in the source code above i fill my D3DPRESENT_PARAMETERS structure with the following code:


D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;



What part of it could be the problem? Checking the created device with PIX the only strange thing i see is that Windowed is set to true if we have specified fullscreen. Still i guess this interesting thing is happening because of the internal workings of PIX - even if i force Windowed to false Pix still tells me that Windowed is false. So i can't really see what could be messing with my application for i-don't-know-how-much-time. I tried playing with the settings and the once that gave me problems didn't return S_OK when creating the device so even if i wanted i couldn't use them.

For your next assumption - yes, clamping the FPS through CPU remedies the problem in fullscreen. Windowed mode still lags but it's not as bad as before.

As for how i'm rendering the cursor:
The windows cursor is on. Additionally that's what i'm doing in my render procedure:

// This source is almost the same as the in the book of Frank Luna,
// called Introduction to 3D Game Programming With DirectX 9.0
// For complete source code see my first post - 3rd code file

Device->Clear(some parameters);
Device->BeginScene();

//Get the current cursor position according to screen coordinates
//Render a texture representing a second cursor in that exact place

Device->EndScene();
Device->Present(0, 0, 0, 0);



No matter how i think about it in the worst case scenario the difference in the position should be at most 1/60 of the second. I don't see how the difference in time between moment 2 and 3 can be more that.
moment 1: Present() at retrace period
moment 2: Render cursor
moment 3: Present() at retrace period

And still the drawn cursor is lagging behind...


#13 Matias Goldberg   Crossbones+   -  Reputation: 3000

Like
0Likes
Like

Posted 21 August 2010 - 09:57 AM

About the fullscreen <-> Win7 issue, seems we can discard that as a problem.

But regarding my questions with mouse cursor, you haven't answered anything meaningful.
For example you say:
Quote:
It's only polling the cursor position

You said you're not using WM_CURSOR, ok, then HOW are you polling the cursor? What function? GetMouseCursorPos? Are you using DirectInput?

#14 Armion   Members   -  Reputation: 272

Like
0Likes
Like

Posted 21 August 2010 - 10:10 AM

I'm sorry i've misunderstood you :) Here is the code you asked for:

	
POINT coords;
::GetCursorPos(&coords);
::ScreenToClient(handle, &coords);

RECT client;
GetClientRect(handle, &client);

// This works correctly for windowed
D3DXVECTOR3 pos(coords.x, coords.y, 0);

sprite->Begin(D3DXSPRITE_ALPHABLEND);
HRESULT test = sprite->Draw(texture, 0, 0, &pos, 0xFFFFFFFF);
sprite->End();




[Edited by - Armion on August 21, 2010 5:10:59 PM]




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS