wined3d: Don't do a logical AND on the swap effect.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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     return E_NOINTERFACE;
81 }
82
83
84 ULONG WINAPI IWineD3DSwapChainImpl_Release(IWineD3DSwapChain *iface) {
85     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
86     DWORD refCount;
87     refCount = InterlockedDecrement(&This->ref);
88     TRACE("(%p) : ReleaseRef to %ld\n", This, refCount);
89     if (refCount == 0) {
90         IUnknown* bufferParent;
91
92         /* tell the device that we've been released */
93         IWineD3DDevice_SwapChainReleased((IWineD3DDevice *)This->wineD3DDevice, iface);
94
95         /* release the ref to the front and back buffer parents */
96         IWineD3DSurface_SetContainer(This->frontBuffer, 0);
97         IWineD3DSurface_GetParent(This->frontBuffer, &bufferParent);
98         IUnknown_Release(bufferParent); /* once for the get parent */
99         if(IUnknown_Release(bufferParent) > 0){
100             FIXME("(%p) Something's still holding the front buffer\n",This);
101         }
102
103         IWineD3DSurface_SetContainer(This->backBuffer, 0);
104         IWineD3DSurface_GetParent(This->backBuffer, &bufferParent);
105         IUnknown_Release(bufferParent); /* once for the get parent */
106         if(IUnknown_Release(bufferParent) > 0){
107             FIXME("(%p) Something's still holding the back buffer\n",This);
108         }
109         /* Clean up the context */
110         /* check that we are the current context first */
111         if(glXGetCurrentContext() == This->glCtx){
112             glXMakeCurrent(This->display, None, NULL);
113         }
114         glXDestroyContext(This->display, This->glCtx);
115         /* IUnknown_Release(This->parent); This should only apply to the primary swapchain,
116          all others are crated by the caller, so releasing the parent should cause
117          the child to be released, not the other way around!
118          */
119         HeapFree(GetProcessHeap(), 0, This);
120     }
121     return refCount;
122 }
123
124 HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface, IUnknown ** ppParent){
125     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
126     *ppParent = This->parent;
127     IUnknown_AddRef(*ppParent);
128     TRACE("(%p) returning %p\n", This , *ppParent);
129     return WINED3D_OK;
130 }
131
132 /*IWineD3DSwapChain parts follow: */
133 HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
134     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
135
136     ENTER_GL();
137
138     if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
139     /* TODO: If only source rect or dest rect are supplied then clip the window to match */
140     TRACE("preseting display %p, drawable %ld\n", This->display, This->drawable);
141
142     /* Don't call checkGLcall, as glGetError is not applicable here */
143     if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
144         /* Set this swapchain up to point to the new destination.. */
145 #ifdef USE_CONTEXT_MANAGER
146             /* TODO: use a context mamager */
147 #endif
148
149             /* FIXME: Never access */
150             IWineD3DSwapChainImpl *swapChainImpl;
151             IWineD3DDevice_GetSwapChain((IWineD3DDevice *)This->wineD3DDevice, 0 , (IWineD3DSwapChain **)&swapChainImpl);
152             FIXME("Unable to render to a destination window %p\n", hDestWindowOverride );
153             if(This == swapChainImpl){
154                 /* FIXME: this will be fixed by moving to a context management system */
155                 FIXME("Cannot change the target of the implicit swapchain\n");
156             }else{
157                 HDC               hDc;
158                 XVisualInfo       template;
159                 int               num;
160                 Display          *oldDisplay = This->display;
161                 GLXContext        oldContext = This->glCtx;
162                 IUnknown*         tmp;
163                 GLXContext        currentContext;
164                 Drawable          currentDrawable;
165                 hDc                          = GetDC(hDestWindowOverride);
166                 This->win_handle             = hDestWindowOverride;
167                 This->win                    = (Window)GetPropA( hDestWindowOverride, "__wine_x11_whole_window" );
168
169                 TRACE("Creating a new context for the window %p\n", hDestWindowOverride);
170                 ENTER_GL();
171                 TRACE("Desctroying context %p %p\n", This->display, This->render_ctx);
172
173
174
175                 LEAVE_GL();
176                 ENTER_GL();
177
178                 This->display    = get_display(hDc);
179                 TRACE("Got display%p  for  %p %p\n",  This->display, hDc, hDestWindowOverride);
180                 ReleaseDC(hDestWindowOverride, hDc);
181                 template.visualid = (VisualID)GetPropA(GetDesktopWindow(), "__wine_x11_visual_id");
182                 This->visInfo   = XGetVisualInfo(This->display, VisualIDMask, &template, &num);
183                 if (NULL == This->visInfo) {
184                     ERR("cannot really get XVisual\n");
185                     LEAVE_GL();
186                     return WINED3DERR_NOTAVAILABLE;
187                 }
188                 /* Now we have problems? well not really we just need to know what the implicit context is */
189                 /* now destroy the old context and create a new one (we should really copy the buffers over, and do the whole make current thing! */
190                 /* destroy the active context?*/
191                 TRACE("Creating new context for %p %p %p\n",This->display, This->visInfo, swapChainImpl->glCtx);
192                 This->glCtx = glXCreateContext(This->display, This->visInfo, swapChainImpl->glCtx, GL_TRUE);
193
194                 if (NULL == This->glCtx) {
195                     ERR("cannot create glxContext\n");
196                 }
197                 This->drawable     = This->win;
198                 This->render_ctx   = This->glCtx;
199                 /* Setup some default states TODO: apply the stateblock to the new context */
200                 /** save current context and drawable **/
201                 currentContext  =   glXGetCurrentContext();
202                 currentDrawable =   glXGetCurrentDrawable();
203
204                 if (glXMakeCurrent(This->display, This->win, This->glCtx) == False) {
205                     ERR("Error in setting current context (display %p context %p drawable %ld)!\n", This->display, This->glCtx, This->win);
206                 }
207
208                 checkGLcall("glXMakeCurrent");
209
210                 /* Clear the screen */
211                 glClearColor(0.0, 0.0, 0.0, 0.0);
212                 checkGLcall("glClearColor");
213                 glClearIndex(0);
214                 glClearDepth(1);
215                 glClearStencil(0);
216
217                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
218                 checkGLcall("glClear");
219
220                 glColor3f(1.0, 1.0, 1.0);
221                 checkGLcall("glColor3f");
222
223                 glEnable(GL_LIGHTING);
224                 checkGLcall("glEnable");
225
226                 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
227                 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);");
228
229                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
230                 checkGLcall("glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
231
232                 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
233                 checkGLcall("glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);");
234
235                 /* If this swapchain is currently the active context then make this swapchain active */
236                 if(IWineD3DSurface_GetContainer(This->wineD3DDevice->renderTarget, &IID_IWineD3DSwapChain, (void **)&tmp) == WINED3D_OK){
237                     if(tmp != (IUnknown *)This){
238                         glXMakeCurrent(This->display, currentDrawable, currentContext);
239                         checkGLcall("glXMakeCurrent");
240                     }
241                     IUnknown_Release(tmp);
242                 }else{
243                     /* reset the context */
244                     glXMakeCurrent(This->display, currentDrawable, currentContext);
245                     checkGLcall("glXMakeCurrent");
246                 }
247                 /* delete the old contxt*/
248                 glXDestroyContext(oldDisplay, oldContext); /* Should this happen on an active context? seems a bad idea */
249                 LEAVE_GL();
250             }
251             IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapChainImpl);
252
253         }
254
255
256         /* 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. */
257
258     glXSwapBuffers(This->display, This->drawable); /* TODO: cycle through the swapchain buffers */
259
260     TRACE("glXSwapBuffers called, Starting new frame\n");
261     /* FPS support */
262     if (TRACE_ON(d3d_fps))
263     {
264         static long prev_time, frames;
265
266         DWORD time = GetTickCount();
267         frames++;
268         /* every 1.5 seconds */
269         if (time - prev_time > 1500) {
270             TRACE_(d3d_fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
271             prev_time = time;
272             frames = 0;
273         }
274     }
275
276 #if defined(FRAME_DEBUGGING)
277 {
278     if (GetFileAttributesA("C:\\D3DTRACE") != INVALID_FILE_ATTRIBUTES) {
279         if (!isOn) {
280             isOn = TRUE;
281             FIXME("Enabling D3D Trace\n");
282             __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 1);
283 #if defined(SHOW_FRAME_MAKEUP)
284             FIXME("Singe Frame snapshots Starting\n");
285             isDumpingFrames = TRUE;
286             glClear(GL_COLOR_BUFFER_BIT);
287 #endif
288
289 #if defined(SINGLE_FRAME_DEBUGGING)
290         } else {
291 #if defined(SHOW_FRAME_MAKEUP)
292             FIXME("Singe Frame snapshots Finishing\n");
293             isDumpingFrames = FALSE;
294 #endif
295             FIXME("Singe Frame trace complete\n");
296             DeleteFileA("C:\\D3DTRACE");
297             __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
298 #endif
299         }
300     } else {
301         if (isOn) {
302             isOn = FALSE;
303 #if defined(SHOW_FRAME_MAKEUP)
304             FIXME("Single Frame snapshots Finishing\n");
305             isDumpingFrames = FALSE;
306 #endif
307             FIXME("Disabling D3D Trace\n");
308             __WINE_SET_DEBUGGING(__WINE_DBCL_TRACE, __wine_dbch_d3d, 0);
309         }
310     }
311 }
312 #endif
313
314     LEAVE_GL();
315     /* Although this is not strictly required, a simple demo showed this does occur
316        on (at least non-debug) d3d                                                  */
317     if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_DISCARD) {
318
319         TRACE("Clearing\n");
320
321         IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, 0x00, 1.0, 0);
322
323     } else {
324         TRACE("Clearing z/stencil buffer\n");
325
326         IWineD3DDevice_Clear((IWineD3DDevice*)This->wineD3DDevice, 0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER, 0x00, 1.0, 0);
327     }
328
329     TRACE("returning\n");
330     return WINED3D_OK;
331 }
332
333 HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
334     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
335     WINED3DFORMAT d3dformat;
336     UINT width;
337     UINT height;
338     WINED3DSURFACE_DESC desc;
339     glDescriptor *glDescription;
340
341     TRACE("(%p) : iface(%p) pDestSurface(%p)\n", This, iface, pDestSurface);
342     ENTER_GL();
343     memset(&desc, 0, sizeof(desc));
344     desc.Width =  &width;
345     desc.Height = &height;
346     desc.Format = &d3dformat;
347 #if 0 /* TODO: make sure that this swapchains context is active */
348     IWineD3DDevice_ActivateSwapChainContext(This->wineD3DDevice, iface);
349 #endif
350     IWineD3DSurface_GetDesc(pDestSurface, &desc);
351     /* make sure that the front buffer is the active read buffer */
352     glReadBuffer(GL_FRONT);
353     /* Read the pixels from the buffer into the surfaces memory */
354     IWineD3DSurface_GetGlDesc(pDestSurface, &glDescription);
355     glReadPixels(glDescription->target,
356                 glDescription->level,
357                 width,
358                 height,
359                 glDescription->glFormat,
360                 glDescription->glType,
361                 (void *)IWineD3DSurface_GetData(pDestSurface));
362     LEAVE_GL();
363     return WINED3D_OK;
364 }
365
366 HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {
367
368     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
369
370     *ppBackBuffer = This->backBuffer;
371     TRACE("(%p) : BackBuf %d Type %d  returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
372
373     if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
374         FIXME("Only one backBuffer currently supported\n");
375         return WINED3DERR_INVALIDCALL;
376     }
377
378     /* Note inc ref on returned surface */
379     IWineD3DSurface_AddRef(*ppBackBuffer);
380     return WINED3D_OK;
381
382 }
383
384 HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, WINED3DRASTER_STATUS *pRasterStatus) {
385     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
386     static BOOL showFixmes = TRUE;
387     pRasterStatus->InVBlank = TRUE;
388     pRasterStatus->ScanLine = 0;
389     /* No openGL equivalent */
390     if(showFixmes) {
391         FIXME("(%p) : stub (once)\n", This);
392         showFixmes = FALSE;
393     }
394     return WINED3D_OK;
395 }
396
397 HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) {
398     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
399     HDC                 hdc;
400     int                 bpp = 0;
401
402     pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
403     pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
404     pMode->RefreshRate  = 85; /* FIXME: How to identify? */
405
406     hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
407     bpp = GetDeviceCaps(hdc, BITSPIXEL);
408     DeleteDC(hdc);
409
410     switch (bpp) {
411     case  8: pMode->Format       = D3DFMT_R8G8B8; break;
412     case 16: pMode->Format       = D3DFMT_R5G6B5; break;
413     case 24: /*pMode->Format       = D3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
414     case 32: pMode->Format       = D3DFMT_A8R8G8B8; break;
415     default:
416        FIXME("Unrecognized display mode format\n");
417        pMode->Format       = D3DFMT_UNKNOWN;
418     }
419
420     TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
421     pMode->Format, debug_d3dformat(pMode->Format));
422     return WINED3D_OK;
423 }
424
425 HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
426     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
427
428     *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
429
430     /* Note  Calling this method will increase the internal reference count
431        on the IDirect3DDevice9 interface. */
432     IWineD3DDevice_AddRef(*ppDevice);
433     TRACE("(%p) : returning %p\n", This, *ppDevice);
434     return WINED3D_OK;
435 }
436
437 HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
438     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
439     TRACE("(%p)\n", This);
440     *pPresentationParameters->BackBufferWidth = This->presentParms.BackBufferWidth;
441     *pPresentationParameters->BackBufferHeight = This->presentParms.BackBufferHeight;
442     *pPresentationParameters->BackBufferFormat = This->presentParms.BackBufferFormat;
443     *pPresentationParameters->BackBufferCount = This->presentParms.BackBufferCount;
444     *pPresentationParameters->MultiSampleType = This->presentParms.MultiSampleType;
445     *pPresentationParameters->MultiSampleQuality = This->presentParms.MultiSampleQuality;
446     *pPresentationParameters->SwapEffect = This->presentParms.SwapEffect;
447     *pPresentationParameters->hDeviceWindow = This->presentParms.hDeviceWindow;
448     *pPresentationParameters->Windowed = This->presentParms.Windowed;
449     *pPresentationParameters->EnableAutoDepthStencil = This->presentParms.EnableAutoDepthStencil;
450     *pPresentationParameters->Flags = This->presentParms.Flags;
451     *pPresentationParameters->FullScreen_RefreshRateInHz = This->presentParms.FullScreen_RefreshRateInHz;
452     *pPresentationParameters->PresentationInterval = This->presentParms.PresentationInterval;
453     return WINED3D_OK;
454 }
455
456 HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp){
457
458     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
459     HDC hDC;
460     TRACE("(%p) : pRamp@%p flags(%ld)\n", This, pRamp, Flags);
461     hDC = GetDC(This->win_handle);
462     SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
463     ReleaseDC(This->win_handle, hDC);
464     return WINED3D_OK;
465
466 }
467
468 HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp){
469
470     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
471     HDC hDC;
472     TRACE("(%p) : pRamp@%p\n", This, pRamp);
473     hDC = GetDC(This->win_handle);
474     GetDeviceGammaRamp(hDC, pRamp);
475     ReleaseDC(This->win_handle, hDC);
476     return WINED3D_OK;
477
478 }
479
480
481 IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
482 {
483     /* IUnknown */
484     IWineD3DSwapChainImpl_QueryInterface,
485     IWineD3DSwapChainImpl_AddRef,
486     IWineD3DSwapChainImpl_Release,
487     /* IWineD3DSwapChain */
488     IWineD3DSwapChainImpl_GetParent,
489     IWineD3DSwapChainImpl_GetDevice,
490     IWineD3DSwapChainImpl_Present,
491     IWineD3DSwapChainImpl_GetFrontBufferData,
492     IWineD3DSwapChainImpl_GetBackBuffer,
493     IWineD3DSwapChainImpl_GetRasterStatus,
494     IWineD3DSwapChainImpl_GetDisplayMode,
495     IWineD3DSwapChainImpl_GetPresentParameters,
496     IWineD3DSwapChainImpl_SetGammaRamp,
497     IWineD3DSwapChainImpl_GetGammaRamp
498 };