diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index ccec8dc..40fd0cf 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -426,12 +463,18 @@ #endif
 static HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
     WINED3DFORMAT d3dformat;
-    UINT width;
-    UINT height;
+    UINT width, height;
     WINED3DSURFACE_DESC desc;
     glDescriptor *glDescription;
+    WINDOWPLACEMENT wpl;
 
     TRACE("(%p) : iface(%p) pDestSurface(%p)\n", This, iface, pDestSurface);
+    
+    if (!GetWindowPlacement(This->win_handle,&wpl)) {
+	FIXME("failed to get window position\n");
+	return WINED3DERR_INVALIDCALL;
+    }
+    
     ENTER_GL();
     memset(&desc, 0, sizeof(desc));
     desc.Width =  &width;
@@ -445,14 +488,34 @@ #endif
     glReadBuffer(GL_FRONT);
     /* Read the pixels from the buffer into the surfaces memory */
     IWineD3DSurface_GetGlDesc(pDestSurface, &glDescription);
-    glReadPixels(glDescription->target,
-                glDescription->level,
+    glReadPixels(-wpl.rcNormalPosition.left,
+                wpl.rcNormalPosition.bottom-height,
                 width,
                 height,
                 glDescription->glFormat,
                 glDescription->glType,
                 (void *)IWineD3DSurface_GetData(pDestSurface));
     LEAVE_GL();
+    {
+	//upside down from glReadPixels data
+	BYTE *row, *top, *bottom;
+	int i;
+	int pitch=width*4; //4 bytes per pixel?
+	row=HeapAlloc(GetProcessHeap(),0,pitch);
+	if (!row) {
+	    ERR("out of memory\n");
+	}
+	top=(void *)IWineD3DSurface_GetData(pDestSurface);
+	bottom= ((BYTE *) (void *)IWineD3DSurface_GetData(pDestSurface))+pitch*(height-1);
+	for (i=0;i<height/2;i++) {
+	    memcpy(row,top,pitch);
+	    memcpy(top,bottom,pitch);
+	    memcpy(bottom,row,pitch);
+	    top+=pitch;
+	    bottom-=pitch;
+	}
+	HeapFree(GetProcessHeap(),0,row);
+    }
     return WINED3D_OK;
 }
 
