user: Added fast 16->32 mapping for the remaining messages.
[wine] / dlls / wined3d / swapchain.c
1 /*
2  *IDirect3DSwapChain9 implementation
3  *
4  *Copyright 2002-2003 Jason Edmeades
5  *Copyright 2002-2003 Raphael Junqueira
6  *Copyright 2005 Oliver Stieber
7  *
8  *This library is free software; you can redistribute it and/or
9  *modify it under the terms of the GNU Lesser General Public
10  *License as published by the Free Software Foundation; either
11  *version 2.1 of the License, or (at your option) any later version.
12  *
13  *This library is distributed in the hope that it will be useful,
14  *but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *Lesser General Public License for more details.
17  *
18  *You should have received a copy of the GNU Lesser General Public
19  *License along with this library; if not, write to the Free Software
20  *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include "config.h"
24 #include "wined3d_private.h"
25
26
27 /* TODO: move to shared header (or context manager )*/
28 /* x11drv GDI escapes */
29 #define X11DRV_ESCAPE 6789
30 enum x11drv_escape_codes
31 {
32     X11DRV_GET_DISPLAY,   /* get X11 display for a DC */
33     X11DRV_GET_DRAWABLE,  /* get current drawable for a DC */
34     X11DRV_GET_FONT,      /* get current X font for a DC */
35 };
36
37 /* retrieve the X display to use on a given DC */
38 inline static Display *get_display( HDC hdc )
39 {
40     Display *display;
41     enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
42
43     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
44                     sizeof(display), (LPSTR)&display )) display = NULL;
45     return display;
46 }
47
48 /*TODO: some of the additional parameters may be required to
49     set the gamma ramp (for some weird reason microsoft have left swap gammaramp in device
50     but it operates on a swapchain, it may be a good idea to move it to IWineD3DSwapChain for IWineD3D)*/
51
52
53 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
54 WINE_DECLARE_DEBUG_CHANNEL(d3d_fps);
55
56
57 /* IDirect3DSwapChain IUnknown parts follow: */
58 ULONG WINAPI IWineD3DSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
59     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
60     DWORD refCount = InterlockedIncrement(&This->ref);
61     TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1);
62     return refCount;
63 }
64
65 HRESULT WINAPI IWineD3DSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, LPVOID *ppobj)
66 {
67     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
68     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj);
69     if (IsEqualGUID(riid, &IID_IUnknown)
70         || IsEqualGUID(riid, &IID_IWineD3DBase)
71         || IsEqualGUID(riid, &IID_IWineD3DSwapChain)){
72         IWineD3DSwapChainImpl_AddRef(iface);
73         if(ppobj == NULL){
74             ERR("Query interface called but now data allocated\n");
75             return E_NOINTERFACE;
76         }
77         *ppobj = This;
78         return WINED3D_OK;
79     }
80     *ppobj = NULL;
81     return E_NOINTERFACE;
82 }
83
84
85 ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
86     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
87     DWORD refCount;
88     refCount = InterlockedDecrement(&This->ref);
89     TRACE("(%p) : ReleaseRef to %ld\n", This, refCount);
90     if (refCount == 0) {
91         IUnknown* bufferParent;
92
93         /* release the ref to the front and back buffer parents */
94         if(This->frontBuffer) {
95             IWineD3DSurface_SetContainer(This->frontBuffer, 0);
96             IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent);
97             IUnknown_Release(bufferParent); /* once for the get parent */
98             if(IUnknown_Release(bufferParent) > 0){
99                 FIXME("(%p) Something's still holding the front buffer\n",This);
100             }
101         }
102
103         if(This->backBuffer) {
104             IWineD3DSurface_SetContainer(This->backBuffer, 0);
105             IWineD3DSurface_GetParent(This->backBuffer, &bufferParent);
106             IUnknown_Release(bufferParent); /* once for the get parent */
107             if(IUnknown_Release(bufferParent) > 0){
108                 FIXME("(%p) Something's still holding the back buffer\n",This);
109             }
110         }
111
112         /* Clean up the context */
113         /* check that we are the current context first */
114         if(glXGetCurrentContext() == This->glCtx){
115             glXMakeCurrent(This->display, None, NULL);
116         }
117         glXDestroyContext(This->display, This->glCtx);
118         /* IUnknown_Release(This->parent); This should only apply to the primary swapchain,
119          all others are crated by the caller, so releasing the parent should cause
120          the child to be released, not the other way around!
121          */
122         HeapFree(GetProcessHeap(), 0, This);
123     }
124     return refCount;
125 }
126
127 HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface, IUnknown ** ppParent){
128     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
129     *ppParent = This->parent;
130     IUnknown_AddRef(*ppParent);
131     TRACE("(%p) returning %p\n", This , *ppParent);
132     return WINED3D_OK;
133 }
134
135 /*IWineD3DSwapChain parts follow: */
136 HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
137     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
138
139     ENTER_GL();
140
141     if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
142     /* TODO: If only source rect or dest rect are supplied then clip the window to match */
143     TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable);
144
145     /* Don't call checkGLcall, as glGetError is not applicable here */
146     if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
147         /* Set this swapchain up to point to the new destination.. */
148 #ifdef USE_CONTEXT_MANAGER
149             /* TODO: use a context mamager */
150 #endif
151
152             /* FIXME: Never access */
153             IWineD3DSwapChainImpl *swapChainImpl;
154             IWineD3DDevice_GetSwapChain((IWineD3DDevice *)This->wineD3DDevice, 0 , (IWineD3DSwapChain **)&swapChainImpl);
155             FIXME("Unable to render to a destination window %p\n", hDestWindowOverride );
156             if(This == swapChainImpl){
157                 /* FIXME: this will be fixed by moving to a context management system */
158                 FIXME("Cannot change the target of the implicit swapchain\n");
159             }else{
160                 HDC               hDc;
161                 XVisualInfo       template;
162                 int               num;
163                 Display          *oldDisplay = This->display;
164                 GLXContext        oldContext = This->glCtx;
165                 IUnknown*         tmp;
166                 GLXContext        currentContext;
167                 Drawable          currentDrawable;
168                 hDc                          = GetDC(hDestWindowOverride);
169                 This->win_handle             = hDestWindowOverride;
170                 This->win                    = (Window)GetPropA( hDestWindowOverride, "__wine_x11_whole_window" );
171
172                 TRACE("Creating a new context for the window %p\n", hDestWindowOverride);
173                 ENTER_GL();
174                 TRACE("Desctroying context %p %p\n", This->display, This->render_ctx);
175
176
177
178                 LEAVE_GL();
179                 ENTER_GL();
180
181                 This->display    = get_display(hDc);
182                 TRACE("Got display%p  for  %p %p\n",  This->display, hDc, hDestWindowOverride);
183                 ReleaseDC(hDestWindowOverride, hDc);
184                 template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
185                 This->visInfo   = XGetVisualInfo(This->display, VisualIDMask, &template, &num);
186                 if (NULL == This->visInfo) {
187                     ERR("cannot really get XVisual\n");
188                     LEAVE_GL();
189                     return WINED3DERR_NOTAVAILABLE;
190                 }
191                 /* Now we have problems? well not really we just need to know what the implicit context is */
192                 /* now destroy the old context and create a new one (we should really copy the buffers over, and do the whole make current thing! */
193                 /* destroy the active context?*/
194                 TRACE("Creating new context for %p %p %p\n",This->display, This->visInfo, swapChainImpl->glCtx);
195                 This->glCtx = glXCreateContext(This->display, This->visInfo, swapChainImpl->glCtx, GL_TRUE);
196
197                 if (NULL == This->glCtx) {
198                     ERR("cannot create glxContext\n");
199                 }
200                 This->drawable     = This->win;
201                 This->render_ctx   = This->glCtx;
202                 /* Setup some default states TODO: apply the stateblock to the new context */
203                 /** save current context and drawable **/
204                 currentContext  =   glXGetCurrentContext();
205                 currentDrawable =   glXGetCurrentDrawable();
206
207                 if (glXMakeCurrent(This->display, This->win, This->glCtx) == False) {
208                     ERR("Error in setting current context (display %p context %p drawable %ld)!\n", This->display, This->glCtx, This->win);
209                 }
210
211                 checkGLcall("glXMakeCurrent");
212
213                 /* Clear the screen */
214                 glClearColor(0.0, 0.0, 0.0, 0.0);
215                 checkGLcall("glClearColor");
216                 glClearIndex(0);
217                 glClearDepth(1);
218                 glClearStencil(0);
219
220                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
221                 checkGLcall("glClear");
222
223                 glColor3f(1.0, 1.0, 1.0);
224                 checkGLcall("glColor3f");
225
226                 glEnable(GL_LIGHTING);
227                 checkGLcall("glEnable");
228
229                 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
230                 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
231
232                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
233                 checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
234
235                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
236                 checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
237
238                 /* If this swapchain is currently the active context then make this swapchain active */
239                 if(IWineD3DSurface_GetContainer(This->wineD3DDevice->renderTarget, &IID_IWineD3DSwapChain, (void **)&tmp) == WINED3D_OK){
240                     if(tmp != (IUnknown *)This){
241                         glXMakeCurrent(This->display, currentDrawable, currentContext);
242                         checkGLcall("glXMakeCurrent");
243                     }
244                     IUnknown_Release(tmp);
245                 }else{
246                     /* reset the context */
247                     glXMakeCurrent(This->display, currentDrawable, currentContext);
248                     checkGLcall("glXMakeCurrent");
249                 }
250                 /* delete the old contxt*/
251                 glXDestroyContext(oldDisplay, oldContext); /* Should this happen on an active context? seems a bad idea */
252                 LEAVE_GL();
253             }
254             IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapChainImpl);
255
256         }
257
258
259         /* TODO: The slow way, save the data to memory, create a new context for the destination window, transfer the data cleanup, it may be a good idea to the move this swapchain over to the using the target winows context so that it runs faster in feature. */
260
261     glXSwapBuffers(This->display, This->drawable); /* TODO: cycle through the swapchain buffers */
262
263     TRACE("glXSwapBuffers called, Starting new frame\n");
264     /* FPS support */
265     if (TRACE_ON(d3d_fps))
266     {
267         static long prev_time, frames;
268
269         DWORD time = GetTickCount();
270         frames++;
271         /* every 1.5 seconds */
272         if (time - prev_time > 1500) {
273             TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
274             prev_time = time;
275             frames = 0;
276         }
277     }
278
279 #if defined(FRAME_DEBUGGING)
280 {
281     if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
282         if (!isOn) {
283             isOn = TRUE;
284             FIXME("Enabling D3D Trace\n");
285             __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
286 #if defined(SHOW_FRAME_MAKEUP)
287             FIXME("Singe Frame snapshots Starting\n");
288             isDumpingFrames = TRUE;
289             glClear(GL_COLOR_BUFFER_BIT);
290 #endif
291
292 #if defined(SINGLE_FRAME_DEBUGGING)
293         } else {
294 #if defined(SHOW_FRAME_MAKEUP)
295             FIXME("Singe Frame snapshots Finishing\n");
296             isDumpingFrames = FALSE;
297 #endif
298             FIXME("Singe Frame trace complete\n");
299             DeleteFileA("C:\\D3DTRACE");
300             __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
301 #endif
302         }
303     } else {
304         if (isOn) {
305             isOn = FALSE;
306 #if defined(SHOW_FRAME_MAKEUP)
307             FIXME("Single Frame snapshots Finishing\n");
308             isDumpingFrames = FALSE;
309 #endif
310             FIXME("Disabling D3D Trace\n");
311             __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
312         }
313     }
314 }
315 #endif
316
317     LEAVE_GL();
318     /* Although this is not strictly required, a simple demo showed this does occur
319        on (at least non-debug) d3d                                                  */
320     if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) {
321
322         TRACE("Clearing\n");
323
324         IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
325
326     } else {
327         TRACE("Clearing z/stencil buffer\n");
328
329         IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER, 0x00, 1.0, 0);
330     }
331
332     TRACE("returning\n");
333     return WINED3D_OK;
334 }
335
336 HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
337     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
338     WINED3DFORMAT d3dformat;
339     UINT width;
340     UINT height;
341     WINED3DSURFACE_DESC desc;
342     glDescriptor *glDescription;
343
344     TRACE("(%p) : iface(%p) pDestSurface(%p)\n", This, iface, pDestSurface);
345     ENTER_GL();
346     memset(&desc, 0, sizeof(desc));
347     desc.Width =  &width;
348     desc.Height = &height;
349     desc.Format = &d3dformat;
350 #if 0 /* TODO: make sure that this swapchains context is active */
351     IWineD3DDevice_ActivateSwapChainContext(This->wineD3DDevice, iface);
352 #endif
353     IWineD3DSurface_GetDesc(pDestSurface, &desc);
354     /* make sure that the front buffer is the active read buffer */
355     glReadBuffer(GL_FRONT);
356     /* Read the pixels from the buffer into the surfaces memory */
357     IWineD3DSurface_GetGlDesc(pDestSurface, &glDescription);
358     glReadPixels(glDescription->target,
359                 glDescription->level,
360                 width,
361                 height,
362                 glDescription->glFormat,
363                 glDescription->glType,
364                 (void *)IWineD3DSurface_GetData(pDestSurface));
365     LEAVE_GL();
366     return WINED3D_OK;
367 }
368
369 HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {
370
371     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
372
373     *ppBackBuffer = This->backBuffer;
374     TRACE("(%p) : BackBuf %d Type %d  returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
375
376     if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
377         TRACE("Back buffer count out of range\n");
378         /* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it here
379          * in wined3d to avoid problems in other libs
380          */
381         *ppBackBuffer = NULL;
382         return WINED3DERR_INVALIDCALL;
383     }
384
385     /* Note inc ref on returned surface */
386     if(*ppBackBuffer) IWineD3DSurface_AddRef(*ppBackBuffer);
387     return WINED3D_OK;
388
389 }
390
391 HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, WINED3DRASTER_STATUS *pRasterStatus) {
392     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
393     static BOOL showFixmes = TRUE;
394     pRasterStatus->InVBlank = TRUE;
395     pRasterStatus->ScanLine = 0;
396     /* No openGL equivalent */
397     if(showFixmes) {
398         FIXME("(%p) : stub (once)\n", This);
399         showFixmes = FALSE;
400     }
401     return WINED3D_OK;
402 }
403
404 HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) {
405     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
406     HDC                 hdc;
407     int                 bpp = 0;
408
409     pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
410     pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
411     pMode->RefreshRate  = 85; /* FIXME: How to identify? */
412
413     hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
414     bpp = GetDeviceCaps(hdc, BITSPIXEL);
415     DeleteDC(hdc);
416
417     switch (bpp) {
418     case  8: pMode->Format       = D3DFMT_R8G8B8; break;
419     case 16: pMode->Format       = D3DFMT_R5G6B5; break;
420     case 24: /*pMode->Format       = D3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
421     case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
422     default:
423        FIXME("Unrecognized display mode format\n");
424        pMode->Format       = D3DFMT_UNKNOWN;
425     }
426
427     TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
428     pMode->Format, debug_d3dformat(pMode->Format));
429     return WINED3D_OK;
430 }
431
432 HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
433     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
434
435     *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
436
437     /* Note  Calling this method will increase the internal reference count
438        on the IDirect3DDevice9 interface. */
439     IWineD3DDevice_AddRef(*ppDevice);
440     TRACE("(%p) : returning %p\n", This, *ppDevice);
441     return WINED3D_OK;
442 }
443
444 HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
445     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
446     TRACE("(%p)\n", This);
447     *pPresentationParameters->BackBufferWidth = This->presentParms.BackBufferWidth;
448     *pPresentationParameters->BackBufferHeight = This->presentParms.BackBufferHeight;
449     *pPresentationParameters->BackBufferFormat = This->presentParms.BackBufferFormat;
450     *pPresentationParameters->BackBufferCount = This->presentParms.BackBufferCount;
451     *pPresentationParameters->MultiSampleType = This->presentParms.MultiSampleType;
452     *pPresentationParameters->MultiSampleQuality = This->presentParms.MultiSampleQuality;
453     *pPresentationParameters->SwapEffect = This->presentParms.SwapEffect;
454     *pPresentationParameters->hDeviceWindow = This->presentParms.hDeviceWindow;
455     *pPresentationParameters->Windowed = This->presentParms.Windowed;
456     *pPresentationParameters->EnableAutoDepthStencil = This->presentParms.EnableAutoDepthStencil;
457     *pPresentationParameters->Flags = This->presentParms.Flags;
458     *pPresentationParameters->FullScreen_RefreshRateInHz = This->presentParms.FullScreen_RefreshRateInHz;
459     *pPresentationParameters->PresentationInterval = This->presentParms.PresentationInterval;
460     return WINED3D_OK;
461 }
462
463 HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp){
464
465     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
466     HDC hDC;
467     TRACE("(%p) : pRamp@%p flags(%ld)\n", This, pRamp, Flags);
468     hDC = GetDC(This->win_handle);
469     SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
470     ReleaseDC(This->win_handle, hDC);
471     return WINED3D_OK;
472
473 }
474
475 HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp){
476
477     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
478     HDC hDC;
479     TRACE("(%p) : pRamp@%p\n", This, pRamp);
480     hDC = GetDC(This->win_handle);
481     GetDeviceGammaRamp(hDC, pRamp);
482     ReleaseDC(This->win_handle, hDC);
483     return WINED3D_OK;
484
485 }
486
487
488 IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
489 {
490     /* IUnknown */
491     IWineD3DSwapChainImpl_QueryInterface,
492     IWineD3DSwapChainImpl_AddRef,
493     IWineD3DSwapChainImpl_Release,
494     /* IWineD3DSwapChain */
495     IWineD3DSwapChainImpl_GetParent,
496     IWineD3DSwapChainImpl_GetDevice,
497     IWineD3DSwapChainImpl_Present,
498     IWineD3DSwapChainImpl_GetFrontBufferData,
499     IWineD3DSwapChainImpl_GetBackBuffer,
500     IWineD3DSwapChainImpl_GetRasterStatus,
501     IWineD3DSwapChainImpl_GetDisplayMode,
502     IWineD3DSwapChainImpl_GetPresentParameters,
503     IWineD3DSwapChainImpl_SetGammaRamp,
504     IWineD3DSwapChainImpl_GetGammaRamp
505 };