2013-05-21 23 views
6

Mamy program, który jest zaprogramowany na SDK DirextX 7 (to znaczy kod używa LPDIRECTDRAWSURFACE7 i podobieństwa) i działa w trybie pełnoekranowym. Głównym zadaniem jest niezawodne dostarczanie czegoś na ekranie w odpowiedzi na zewnętrzne wyzwalacze. To działa bardzo dobrze w systemie Windows XP: bsically oprogramowanie czeka na jakiś wyzwalacz i po uruchomieniu tworzy nową ramkę, umieszcza ją w buforze wstecznym, a następnie mówi DX, aby odwrócić bufory. Rezultatem jest przybliżone opóźnienie między wyzwalaczem a faktycznym wyświetleniem ramki na ekranie, w zależności od karty graficznej i sterowników, 3 klatek lub 50 msSec dla ekranu 60 Hz. Jest to testowane na różnych systemach, z wszystkimi kartami NVidia. W niektórych systemach z wyższymi kartami końcowymi otrzymujemy nawet 2 ramki.Naprawiono opóźnienie DirectX 7 w systemie Windows 7?

Podczas korzystania z tego samego oprogramowania w systemie Windows 7 (bez żadnego innego zainstalowanego oprogramowania) nie możemy uzyskać mniej niż 5 ramek. Znaczenie gdzieś w rurociągu system operacyjny lub sterownik albo obie osoby jedzą 2 dodatkowe ramki, co jest niedopuszczalne dla aplikacji. Próbowaliśmy wyłączyć kompozycję aero/desktop/różne wersje sterowników/różne karty graficzne, ale bez skutku.

  • skąd się to bierze? czy to gdzieś dokumentuje?
  • Czy istnieje prosty sposób na naprawę? Wiem, że DirectX 7 jest stary, ale uaktualnienie do kompilacji, a nowsze wersje mogą być mnóstwo pracy, więc inny rodzaj poprawki byłoby miłe. Może jakaś flaga, którą można ustawić w kodzie?

edit Oto niektóre kodu, który wydaje się istotne:

Stworzenie przód/tył powierzchnie:

ddraw7->SetCooperativeLevel(GetSafeHwnd(), 
    DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED) 

DDSURFACEDESC2 desc; 
ZeroMemory(&desc, sizeof(desc)); 
desc.dwSize = sizeof(desc); 
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | 
         DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE | 
         DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; 
desc.dwBackBufferCount = 1; 
ddraw7->CreateSurface(&desc, &primsurf, 0) 

DDSCAPS2 surfcaps; 
ZeroMemory(&surfcaps,sizeof(surfcaps)); 
surfcaps.dwCaps = DDSCAPS_BACKBUFFER; 
primsurf->GetAttachedSurface(&surfcaps, &backsurf); 

Stworzenie powierzchniach wykorzystywanych do renderowania klatek zanim zostaną one sporządzone:

DDSURFACEDESC2 desc; 
ZeroMemory(&desc, sizeof(desc)); 
desc.dwSize = sizeof(desc); 
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ; 
desc.dwWidth = w; 
desc.dwHeight = h; 
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; 
desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); 
desc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8; 

LPDIRECTDRAWSURFACE7 surf; 
HRESULT r=ddraw7->CreateSurface(&desc, &surf, 0) 

Pętla renderowania, w OnIdle:

//clear surface 
DDBLTFX bltfx; 
ZeroMemory(&bltfx, sizeof(bltfx)); 
bltfx.dwSize = sizeof(bltfx); 
bltfx.dwFillColor = RGBtoPixel(r, g, b); 
backsurf->Blt(rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx) 

//blit some prerendered surface onto it, x/y/rect etc are calculated properly) 
backsurf->BltFast(x, y, sourceSurf, s&sourceRect, DDBLTFAST_WAIT); 

primsurf->Flip(0, DDFLIP_WAIT) 

primsurf->Blt(&drect,backsurf,&srect,DDBLT_WAIT,0); 
+0

Chcesz wyjaśnić, dlaczego jest on odrzucany? Jeśli na przykład tutaj nie pasuje, powiedz przynajmniej dlaczego. – stijn

+0

zapytaj na stackoverflow, ponieważ jest to pytanie o kodowanie. – magicandre1981

+0

Tak, nie byłem pewien, możliwe, że jest to tylko problem z konfiguracją - mimo to przegłosowano, aby przejść do SO – stijn

Odpowiedz

3

Myślę, że Windows XP to czerwony śledzia. Ostatnią wersją systemu Windows, na którym DirectX 7 działał bezpośrednio, był Windows 2000. Windows XP po prostu emuluje DX7 w DX9, tak jak robi to Windows 7.

Podejrzewam, że twoja aplikacja korzysta z paletyzowanych tekstur, a kiedy DX emuluje tę funkcjonalność (ponieważ została upuszczona po DX7), generuje teksturę za pomocą indeksowanych kolorów. Możesz wypróbować profilowanie aplikacji za pomocą GPUView, aby sprawdzić, czy opóźnienie w przepychaniu tekstur do procesora graficznego jest opóźnione. Np. Być może sterownik Win7 najpierw ją kompresuje?

+0

nie używamy paletyzowanych tekstur ani żadnej innej specjalnej kompozycji DX: wszystko jest zapisywane piksel po pikselu bezpośrednio do pamięci powierzchni. Ale dzięki za wzmiankę o GPUView, nie wiedziałem o tym, ale wydaje się to bardzo interesujące. – stijn

+0

@stijn uruchamiasz jakiekolwiek shadery? –

+0

no; nie ma kodu atm ale afaik pętla renderowania po prostu ustawia niektóre piksele na powierzchni, rozciera powierzchnię na powierzchnię bufora wstecznego i wywołuje Flip() – stijn

Powiązane problemy