mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 10:13:56 +00:00
wined3d: Implement vertical refresh sync.
This commit is contained in:
parent
43fda1f4f0
commit
c9b8a79e0b
7 changed files with 102 additions and 4 deletions
|
@ -1064,6 +1064,10 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) {
|
||||||
}
|
}
|
||||||
memcpy(ThisExtn, Start, (GLX_Extensions - Start));
|
memcpy(ThisExtn, Start, (GLX_Extensions - Start));
|
||||||
TRACE_(d3d_caps)("- %s\n", ThisExtn);
|
TRACE_(d3d_caps)("- %s\n", ThisExtn);
|
||||||
|
if (strstr(ThisExtn, "GLX_SGI_video_sync")) {
|
||||||
|
gl_info->supported[SGI_VIDEO_SYNC] = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (*GLX_Extensions == ' ') GLX_Extensions++;
|
if (*GLX_Extensions == ' ') GLX_Extensions++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2355,7 +2355,8 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) {
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) {
|
static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) {
|
||||||
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
|
||||||
IWineD3DDevice *D3D = (IWineD3DDevice *) This->resource.wineD3DDevice;
|
IWineD3DSwapChainImpl *swapchain = NULL;
|
||||||
|
HRESULT hr;
|
||||||
TRACE("(%p)->(%p,%x)\n", This, override, Flags);
|
TRACE("(%p)->(%p,%x)\n", This, override, Flags);
|
||||||
|
|
||||||
/* Flipping is only supported on RenderTargets */
|
/* Flipping is only supported on RenderTargets */
|
||||||
|
@ -2369,8 +2370,32 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DS
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **) &swapchain);
|
||||||
|
if(!swapchain) {
|
||||||
|
ERR("Flipped surface is not on a swapchain\n");
|
||||||
|
return WINEDDERR_NOTFLIPPABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Just overwrite the swapchain presentation interval. This is ok because only ddraw apps can call Flip,
|
||||||
|
* and only d3d8 and d3d9 apps specify the presentation interval
|
||||||
|
*/
|
||||||
|
if((Flags & (WINEDDFLIP_NOVSYNC | WINEDDFLIP_INTERVAL2 | WINEDDFLIP_INTERVAL3 | WINEDDFLIP_INTERVAL4)) == 0) {
|
||||||
|
/* Most common case first to avoid wasting time on all the other cases */
|
||||||
|
swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_ONE;
|
||||||
|
} else if(Flags & WINEDDFLIP_NOVSYNC) {
|
||||||
|
swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_IMMEDIATE;
|
||||||
|
} else if(Flags & WINEDDFLIP_INTERVAL2) {
|
||||||
|
swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_TWO;
|
||||||
|
} else if(Flags & WINEDDFLIP_INTERVAL3) {
|
||||||
|
swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_THREE;
|
||||||
|
} else {
|
||||||
|
swapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_FOUR;
|
||||||
|
}
|
||||||
|
|
||||||
/* Flipping a OpenGL surface -> Use WineD3DDevice::Present */
|
/* Flipping a OpenGL surface -> Use WineD3DDevice::Present */
|
||||||
return IWineD3DDevice_Present(D3D, NULL, NULL, 0, NULL);
|
hr = IWineD3DSwapChain_Present((IWineD3DSwapChain *) swapchain, NULL, NULL, 0, NULL, 0);
|
||||||
|
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does a direct frame buffer -> texture copy. Stretching is done
|
/* Does a direct frame buffer -> texture copy. Stretching is done
|
||||||
|
@ -2773,10 +2798,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dstSwapchain->presentParms.SwapEffect = WINED3DSWAPEFFECT_COPY;
|
dstSwapchain->presentParms.SwapEffect = WINED3DSWAPEFFECT_COPY;
|
||||||
|
dstSwapchain->presentParms.PresentationInterval = WINED3DPRESENT_INTERVAL_IMMEDIATE;
|
||||||
|
|
||||||
TRACE("Full screen back buffer -> front buffer blt, performing a flip instead\n");
|
TRACE("Full screen back buffer -> front buffer blt, performing a flip instead\n");
|
||||||
IWineD3DDevice_Present((IWineD3DDevice *) This->resource.wineD3DDevice,
|
IWineD3DSwapChain_Present((IWineD3DSwapChain *) dstSwapchain, NULL, NULL, 0, NULL, 0);
|
||||||
NULL, NULL, 0, NULL);
|
|
||||||
|
|
||||||
dstSwapchain->presentParms.SwapEffect = orig_swap;
|
dstSwapchain->presentParms.SwapEffect = orig_swap;
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ static inline Display *get_display( HDC hdc )
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(fps);
|
WINE_DECLARE_DEBUG_CHANNEL(fps);
|
||||||
|
|
||||||
|
#define GLINFO_LOCATION This->wineD3DDevice->adapter->gl_info
|
||||||
|
|
||||||
/* IDirect3DSwapChain IUnknown parts follow: */
|
/* IDirect3DSwapChain IUnknown parts follow: */
|
||||||
static ULONG WINAPI IWineD3DSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
|
static ULONG WINAPI IWineD3DSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
|
||||||
|
@ -148,6 +149,8 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
|
||||||
static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
|
static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
|
||||||
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
|
||||||
DWORD clear_flags = 0;
|
DWORD clear_flags = 0;
|
||||||
|
unsigned int sync;
|
||||||
|
int retval;
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
|
|
||||||
|
@ -374,6 +377,47 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE && GL_SUPPORT(SGI_VIDEO_SYNC)) {
|
||||||
|
retval = GL_EXTCALL(glXGetVideoSyncSGI(&sync));
|
||||||
|
if(retval != 0) {
|
||||||
|
ERR("glXGetVideoSyncSGI failed(retval = %d\n", retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(This->presentParms.PresentationInterval) {
|
||||||
|
case WINED3DPRESENT_INTERVAL_DEFAULT:
|
||||||
|
case WINED3DPRESENT_INTERVAL_ONE:
|
||||||
|
if(sync <= This->vSyncCounter) {
|
||||||
|
retval = GL_EXTCALL(glXWaitVideoSyncSGI(1, 0, &This->vSyncCounter));
|
||||||
|
} else {
|
||||||
|
This->vSyncCounter = sync;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WINED3DPRESENT_INTERVAL_TWO:
|
||||||
|
if(sync <= This->vSyncCounter + 1) {
|
||||||
|
retval = GL_EXTCALL(glXWaitVideoSyncSGI(2, This->vSyncCounter & 0x1, &This->vSyncCounter));
|
||||||
|
} else {
|
||||||
|
This->vSyncCounter = sync;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WINED3DPRESENT_INTERVAL_THREE:
|
||||||
|
if(sync <= This->vSyncCounter + 2) {
|
||||||
|
retval = GL_EXTCALL(glXWaitVideoSyncSGI(3, This->vSyncCounter % 0x3, &This->vSyncCounter));
|
||||||
|
} else {
|
||||||
|
This->vSyncCounter = sync;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WINED3DPRESENT_INTERVAL_FOUR:
|
||||||
|
if(sync <= This->vSyncCounter + 3) {
|
||||||
|
retval = GL_EXTCALL(glXWaitVideoSyncSGI(4, This->vSyncCounter & 0x3, &This->vSyncCounter));
|
||||||
|
} else {
|
||||||
|
This->vSyncCounter = sync;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FIXME("Unknown presentation interval %08x\n", This->presentParms.PresentationInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("returning\n");
|
TRACE("returning\n");
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1404,6 +1404,7 @@ typedef struct IWineD3DSwapChainImpl
|
||||||
WINED3DFORMAT orig_fmt;
|
WINED3DFORMAT orig_fmt;
|
||||||
|
|
||||||
long prev_time, frames; /* Performance tracking */
|
long prev_time, frames; /* Performance tracking */
|
||||||
|
unsigned int vSyncCounter;
|
||||||
|
|
||||||
WineD3DContext **context; /* Later a array for multithreading */
|
WineD3DContext **context; /* Later a array for multithreading */
|
||||||
unsigned int num_contexts;
|
unsigned int num_contexts;
|
||||||
|
|
|
@ -241,6 +241,10 @@ typedef struct IDirectDrawGammaControl *LPDIRECTDRAWGAMMACONTROL;
|
||||||
#define DDFLIP_NOVSYNC 0x00000008
|
#define DDFLIP_NOVSYNC 0x00000008
|
||||||
#define DDFLIP_STEREO 0x00000010
|
#define DDFLIP_STEREO 0x00000010
|
||||||
#define DDFLIP_DONOTWAIT 0x00000020
|
#define DDFLIP_DONOTWAIT 0x00000020
|
||||||
|
#define DDFLIP_INTERVAL2 0x02000000
|
||||||
|
#define DDFLIP_INTERVAL3 0x03000000
|
||||||
|
#define DDFLIP_INTERVAL4 0x04000000
|
||||||
|
|
||||||
|
|
||||||
/* dwFlags for GetBltStatus */
|
/* dwFlags for GetBltStatus */
|
||||||
#define DDGBS_CANBLT 0x00000001
|
#define DDGBS_CANBLT 0x00000001
|
||||||
|
|
|
@ -1225,6 +1225,10 @@ typedef void (APIENTRY * PGLFNTEXBUMPPARAMETERFVATIPROC) (GLenum, GLfloat *);
|
||||||
typedef void (APIENTRY * PGLFNGETTEXBUMPPARAMETERIVATIPROC) (GLenum, GLint *);
|
typedef void (APIENTRY * PGLFNGETTEXBUMPPARAMETERIVATIPROC) (GLenum, GLint *);
|
||||||
typedef void (APIENTRY * PGLFNGETTEXBUMPPARAMETERFVATIPROC) (GLenum, GLfloat *);
|
typedef void (APIENTRY * PGLFNGETTEXBUMPPARAMETERFVATIPROC) (GLenum, GLfloat *);
|
||||||
|
|
||||||
|
/* GLX_SGI_video_sync */
|
||||||
|
typedef int (APIENTRY * PGLXFNGETVIDEOSYNCSGIPROC) (unsigned int *);
|
||||||
|
typedef int (APIENTRY * PGLXFNWAITVIDEOSYNCSGIPROC) (int, int, unsigned int *);
|
||||||
|
|
||||||
/* GL_VERSION_2_0 */
|
/* GL_VERSION_2_0 */
|
||||||
#ifndef GL_VERSION_2_0
|
#ifndef GL_VERSION_2_0
|
||||||
#define GL_VERSION_2_0 1
|
#define GL_VERSION_2_0 1
|
||||||
|
@ -1593,6 +1597,8 @@ typedef enum _GL_SupportedExt {
|
||||||
/* APPLE */
|
/* APPLE */
|
||||||
APPLE_FENCE,
|
APPLE_FENCE,
|
||||||
APPLE_CLIENT_STORAGE,
|
APPLE_CLIENT_STORAGE,
|
||||||
|
/* SGI */
|
||||||
|
SGI_VIDEO_SYNC,
|
||||||
|
|
||||||
OPENGL_SUPPORTED_EXT_END
|
OPENGL_SUPPORTED_EXT_END
|
||||||
} GL_SupportedExt;
|
} GL_SupportedExt;
|
||||||
|
@ -1817,6 +1823,9 @@ typedef enum _GL_SupportedExt {
|
||||||
USE_GL_FUNC(PGLFNTEXBUMPPARAMETERFVATIPROC, glTexBumpParameterfvATI); \
|
USE_GL_FUNC(PGLFNTEXBUMPPARAMETERFVATIPROC, glTexBumpParameterfvATI); \
|
||||||
USE_GL_FUNC(PGLFNGETTEXBUMPPARAMETERIVATIPROC, glGetTexBumpParameterivATI); \
|
USE_GL_FUNC(PGLFNGETTEXBUMPPARAMETERIVATIPROC, glGetTexBumpParameterivATI); \
|
||||||
USE_GL_FUNC(PGLFNGETTEXBUMPPARAMETERFVATIPROC, glGetTexBumpParameterfvATI); \
|
USE_GL_FUNC(PGLFNGETTEXBUMPPARAMETERFVATIPROC, glGetTexBumpParameterfvATI); \
|
||||||
|
/* GLX_SGI_video_sync */ \
|
||||||
|
USE_GL_FUNC(PGLXFNGETVIDEOSYNCSGIPROC, glXGetVideoSyncSGI); \
|
||||||
|
USE_GL_FUNC(PGLXFNWAITVIDEOSYNCSGIPROC, glXWaitVideoSyncSGI); \
|
||||||
|
|
||||||
/* OpenGL 2.0 functions */
|
/* OpenGL 2.0 functions */
|
||||||
#define GL2_FUNCS_GEN \
|
#define GL2_FUNCS_GEN \
|
||||||
|
|
|
@ -1759,4 +1759,15 @@ typedef struct _WINEDDOVERLAYFX
|
||||||
#define WINEDDGFS_CANFLIP 1L
|
#define WINEDDGFS_CANFLIP 1L
|
||||||
#define WINEDDGFS_ISFLIPDONE 2L
|
#define WINEDDGFS_ISFLIPDONE 2L
|
||||||
|
|
||||||
|
/* dwFlags for Flip */
|
||||||
|
#define WINEDDFLIP_WAIT 0x00000001
|
||||||
|
#define WINEDDFLIP_EVEN 0x00000002 /* only valid for overlay */
|
||||||
|
#define WINEDDFLIP_ODD 0x00000004 /* only valid for overlay */
|
||||||
|
#define WINEDDFLIP_NOVSYNC 0x00000008
|
||||||
|
#define WINEDDFLIP_STEREO 0x00000010
|
||||||
|
#define WINEDDFLIP_DONOTWAIT 0x00000020
|
||||||
|
#define WINEDDFLIP_INTERVAL2 0x02000000
|
||||||
|
#define WINEDDFLIP_INTERVAL3 0x03000000
|
||||||
|
#define WINEDDFLIP_INTERVAL4 0x04000000
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue