Changelog: - fix some regressions - GetDC does not lock in ReadOnly mode as it leads to problems with some D3D optimizations - added a fast Back => Front / Front => Back Blt fast path -- Lionel Ulmer - http://www.bbrox.org/
--- dlls/ddraw_CVS/d3ddevice/mesa.c Sun Jun 15 02:09:27 2003 +++ dlls/ddraw/d3ddevice/mesa.c Sun Jun 15 18:37:35 2003 @@ -2684,6 +2684,83 @@ LEAVE_GL(); return DD_OK; + } else if ((dwFlags & (~(DDBLT_WAIT|DDBLT_ASYNC))) == 0) { + /* Normal blit without any special case... */ + if (src != NULL) { + /* And which has a SRC surface */ + IDirectDrawSurfaceImpl *src_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); + if ((src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && + (src_impl->d3ddevice == This->d3ddevice)) { + /* Both are 3D devices and using the same GL device */ + D3DRECT src_rect; + int width, height; + GLenum prev_draw; + WINE_GL_BUFFER_TYPE src_buffer_type; + IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice; + + if (rsrc) { + src_rect.u1.x1 = rsrc->left; + src_rect.u2.y1 = rsrc->top; + src_rect.u3.x2 = rsrc->right; + src_rect.u4.y2 = rsrc->bottom; + } else { + src_rect.u1.x1 = 0; + src_rect.u2.y1 = 0; + src_rect.u3.x2 = src_impl->surface_desc.dwWidth; + src_rect.u4.y2 = src_impl->surface_desc.dwHeight; + } + + width = src_rect.u3.x2 - src_rect.u1.x1; + height = src_rect.u4.y2 - src_rect.u2.y1; + + if ((width != (src_rect.u3.x2 - src_rect.u1.x1)) || + (height != (src_rect.u4.y2 - src_rect.u2.y1))) { + TRACE(" buffer to buffer copy not supported with stretching yet !\n"); + return DDERR_INVALIDPARAMS; + } + + /* First check if we BLT from the backbuffer... */ + if ((src_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) != 0) { + src_buffer_type = WINE_GL_BUFFER_BACK; + } else if ((src_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) { + src_buffer_type = WINE_GL_BUFFER_FRONT; + } else { + ERR("Unexpected case in direct buffer to buffer copy !\n"); + return DDERR_INVALIDPARAMS; + } + + TRACE(" using direct buffer to buffer copy.\n"); + + ENTER_GL(); + + glGetIntegerv(GL_DRAW_BUFFER, &prev_draw); + if (buffer_type == WINE_GL_BUFFER_FRONT) + glDrawBuffer(GL_FRONT); + else + glDrawBuffer(GL_BACK); + + if (src_buffer_type == WINE_GL_BUFFER_FRONT) + glReadBuffer(GL_FRONT); + else + glReadBuffer(GL_BACK); + + /* Set orthographic projection to prevent bad things happening with the glRasterPos call */ + if (gl_d3d_dev->transform_state != GL_TRANSFORM_ORTHO) { + gl_d3d_dev->transform_state = GL_TRANSFORM_ORTHO; + d3ddevice_set_ortho(This->d3ddevice); + } + + glRasterPos3d(rect.u1.x1, rect.u2.y1, 0.5); + glCopyPixels(src_rect.u1.x1, src_impl->surface_desc.dwHeight - rect.u4.y2, + width, height, GL_COLOR); + + if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) || + ((buffer_type == WINE_GL_BUFFER_BACK) && (prev_draw == GL_FRONT))) + glDrawBuffer(prev_draw); + + LEAVE_GL(); + } + } } return DDERR_INVALIDPARAMS; } --- dlls/ddraw_CVS/dsurface/main.c Sat Jun 14 00:41:02 2003 +++ dlls/ddraw/dsurface/main.c Sun Jun 15 15:52:17 2003 @@ -794,7 +794,7 @@ * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another * thread has it locked, but GetDC does not. */ ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, DDLOCK_READONLY, 0); + hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, 0, 0); if (FAILED(hr)) { UNLOCK_OBJECT(This); --- dlls/ddraw_CVS/gl_api.h Thu Jun 5 01:10:38 2003 +++ dlls/ddraw/gl_api.h Sun Jun 15 18:38:52 2003 @@ -39,6 +39,7 @@ GL_API_FUNCTION(glColor3ub) GL_API_FUNCTION(glColor4ub) GL_API_FUNCTION(glColorMaterial) +GL_API_FUNCTION(glCopyPixels) GL_API_FUNCTION(glCopyTexSubImage2D) GL_API_FUNCTION(glCullFace) GL_API_FUNCTION(glDeleteTextures) @@ -79,7 +80,7 @@ GL_API_FUNCTION(glPolygonOffset) GL_API_FUNCTION(glPopMatrix) GL_API_FUNCTION(glPushMatrix) -GL_API_FUNCTION(glRasterPos2f) +GL_API_FUNCTION(glRasterPos3d) GL_API_FUNCTION(glReadBuffer) GL_API_FUNCTION(glReadPixels) GL_API_FUNCTION(glScissor) --- dlls/ddraw_CVS/gl_private.h Thu Jun 5 01:10:38 2003 +++ dlls/ddraw/gl_private.h Sun Jun 15 18:39:24 2003 @@ -63,6 +63,7 @@ #define glColor3f pglColor3f #define glColor3ub pglColor3ub #define glColor4ub pglColor4ub +#define glCopyPixels pglCopyPixels #define glCopyTexSubImage2D pglCopyTexSubImage2D #define glColorMaterial pglColorMaterial #define glCullFace pglCullFace @@ -104,7 +105,7 @@ #define glPolygonOffset pglPolygonOffset #define glPopMatrix pglPopMatrix #define glPushMatrix pglPushMatrix -#define glRasterPos2f pglRasterPos2f +#define glRasterPos3d pglRasterPos3d #define glReadBuffer pglReadBuffer #define glReadPixels pglReadPixels #define glScissor pglScissor --- dlls/ddraw_CVS/mesa.c Sun Jun 15 02:09:27 2003 +++ dlls/ddraw/mesa.c Sun Jun 15 15:49:30 2003 @@ -147,15 +147,21 @@ updated either.. No idea about what happens in D3D. Maybe replacing the Z function by ALWAYS would be a better idea. */ - if ((dwRenderState == D3DZB_TRUE) && (glThis->depth_test == FALSE)) { - glEnable(GL_DEPTH_TEST); - glThis->depth_test = TRUE; - } else if ((dwRenderState == D3DZB_FALSE) && (glThis->depth_test == TRUE)) { - glDisable(GL_DEPTH_TEST); - glThis->depth_test = FALSE; - } else if (glThis->depth_test == FALSE) { - glEnable(GL_DEPTH_TEST); - glThis->depth_test = TRUE; + if (dwRenderState == D3DZB_TRUE) { + if (glThis->depth_test == FALSE) { + glEnable(GL_DEPTH_TEST); + glThis->depth_test = TRUE; + } + } else if (dwRenderState == D3DZB_FALSE) { + if (glThis->depth_test == TRUE) { + glDisable(GL_DEPTH_TEST); + glThis->depth_test = FALSE; + } + } else { + if (glThis->depth_test == FALSE) { + glEnable(GL_DEPTH_TEST); + glThis->depth_test = TRUE; + } WARN(" w-buffering not supported.\n"); } break;