From 8daf96c20357298f5179aa6670bbbaf47ccfbe26 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Tue, 20 May 2003 04:10:22 +0000 Subject: [PATCH] - fix bug in 'Blt DEPTH_FILL' override - added a lock around the flushing of a surface to the frame buffer - optimize texture loading my minimizing the cases where a conversion needs to occur and also by reusing the allocated memory --- dlls/ddraw/d3ddevice/main.c | 2 +- dlls/ddraw/d3ddevice/mesa.c | 24 +++-- dlls/ddraw/d3dtexture.c | 174 ++++++++++++++++++++++-------------- dlls/ddraw/mesa_private.h | 3 + 4 files changed, 130 insertions(+), 73 deletions(-) diff --git a/dlls/ddraw/d3ddevice/main.c b/dlls/ddraw/d3ddevice/main.c index 91f74597ea2..8ee987d1ee1 100644 --- a/dlls/ddraw/d3ddevice/main.c +++ b/dlls/ddraw/d3ddevice/main.c @@ -929,7 +929,7 @@ Main_IDirect3DDeviceImpl_7_Load(LPDIRECT3DDEVICE7 iface, ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); FIXME("(%p/%p)->(%p,%p,%p,%p,%08lx): Partially Implemented!\n", This, iface, lpDestTex, lpDestPoint, lpSrcTex, lprcSrcRect, dwFlags); IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, lpDestTex), - COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, lpSrcTex)); + COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, lpSrcTex)); return DD_OK; } diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c index 73c29702276..bb6fec62c5f 100644 --- a/dlls/ddraw/d3ddevice/mesa.c +++ b/dlls/ddraw/d3ddevice/mesa.c @@ -109,7 +109,7 @@ static BOOL opengl_flip( LPVOID dev, LPVOID drawable) { IDirect3DDeviceImpl *d3d_dev = (IDirect3DDeviceImpl *) dev; IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) dev; - + TRACE("(%p, %ld)\n", gl_d3d_dev->display,(Drawable)drawable); ENTER_GL(); if (gl_d3d_dev->state == SURFACE_MEMORY) { @@ -119,6 +119,7 @@ static BOOL opengl_flip( LPVOID dev, LPVOID drawable) gl_d3d_dev->front_state = SURFACE_GL; glXSwapBuffers(gl_d3d_dev->display, (Drawable)drawable); LEAVE_GL(); + return TRUE; } @@ -2523,12 +2524,16 @@ d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst, /* This is easy to handle for the D3D Device... */ DWORD color = lpbltfx->u5.dwFillColor; D3DRECT rect; + TRACE(" executing D3D Device override.\n"); - rect.u1.x1 = rdst->left; - rect.u2.y1 = rdst->top; - rect.u3.x2 = rdst->right; - rect.u4.y2 = rdst->bottom; - d3ddevice_clear(This->d3ddevice, 1, &rect, D3DCLEAR_TARGET, color, 0.0, 0x00000000); + + if (rdst) { + rect.u1.x1 = rdst->left; + rect.u2.y1 = rdst->top; + rect.u3.x2 = rdst->right; + rect.u4.y2 = rdst->bottom; + } + d3ddevice_clear(This->d3ddevice, rdst != NULL ? 1 : 0, &rect, D3DCLEAR_TARGET, color, 0.0, 0x00000000); return DD_OK; } return DDERR_INVALIDPARAMS; @@ -2845,6 +2850,9 @@ static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCREC GLint tex_state; int x, y; + /* This is to prevent another thread to actually lock the buffer while we flush it on screen */ + EnterCriticalSection(&(d3d_dev->crit)); + loc_rect.top = 0; loc_rect.left = 0; loc_rect.bottom = surf->surface_desc.dwHeight; @@ -2884,6 +2892,7 @@ static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCREC glPixelStorei(GL_UNPACK_SWAP_BYTES, TRUE); } else { ERR(" unsupported pixel format at frame buffer flush.\n"); + LeaveCriticalSection(&(d3d_dev->crit)); return; } @@ -2973,6 +2982,9 @@ static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCREC } } #endif + + /* And leave the critical section... */ + LeaveCriticalSection(&(d3d_dev->crit)); } static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect) diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c index a4fe99cc7ae..b0f35852615 100644 --- a/dlls/ddraw/d3dtexture.c +++ b/dlls/ddraw/d3dtexture.c @@ -102,7 +102,7 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { surf_ptr = This; while (surf_ptr != NULL) { - GLenum format = GL_RGBA, pixel_format = GL_UNSIGNED_BYTE; /* This is only to prevent warnings.. */ + GLenum internal_format = GL_RGBA, format = GL_RGBA, pixel_format = GL_UNSIGNED_BYTE; /* This is only to prevent warnings.. */ VOID *surface = NULL; DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(surf_ptr->surface_desc); IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private; @@ -177,8 +177,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { } else { DWORD i; BYTE *src = (BYTE *) src_d->lpSurface, *dst; - - surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); dst = (BYTE *) surface; for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { @@ -190,6 +193,7 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { } format = GL_RGBA; + internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_BYTE; } } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) { @@ -209,6 +213,7 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { error = TRUE; } else { format = GL_RGB; + internal_format = GL_RGB; pixel_format = GL_UNSIGNED_BYTE_3_3_2; } } else { @@ -233,8 +238,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { DWORD i; WORD *src = (WORD *) src_d->lpSurface, *dst; - surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); dst = (WORD *) surface; for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { WORD color = *src++; @@ -246,9 +254,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { } format = GL_RGBA; + internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; } else { format = GL_RGB; + internal_format = GL_RGB; pixel_format = GL_UNSIGNED_SHORT_5_6_5; } } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) && @@ -256,14 +266,18 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x003E) && (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) { format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; if (src_d->dwFlags & DDSD_CKSRCBLT) { /* Change the alpha value of the color-keyed pixels to emulate color-keying. */ DWORD i; WORD *src = (WORD *) src_d->lpSurface, *dst; - surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); dst = (WORD *) surface; for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { WORD color = *src++; @@ -279,14 +293,18 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x00F0) && (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) { format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; if (src_d->dwFlags & DDSD_CKSRCBLT) { /* Change the alpha value of the color-keyed pixels to emulate color-keying. */ DWORD i; WORD *src = (WORD *) src_d->lpSurface, *dst; - surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); dst = (WORD *) surface; for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { WORD color = *src++; @@ -302,14 +320,17 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000F) && (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) { /* Move the four Alpha bits... */ - DWORD i; - WORD *src = (WORD *) src_d->lpSurface, *dst; - - surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); - dst = surface; - if (src_d->dwFlags & DDSD_CKSRCBLT) { + DWORD i; + WORD *src = (WORD *) src_d->lpSurface, *dst; + + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + dst = surface; + for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { WORD color = *src++; *dst = (color & 0x0FFF) << 4; @@ -318,29 +339,29 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { *dst |= (color & 0xF000) >> 12; dst++; } + format = GL_RGBA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; } else { - for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { - WORD color = *src++; - *dst++ = (((color & 0x0FFF) << 4) | - ((color & 0xF000) >> 12)); - } + format = GL_BGRA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV; } - - format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x7C00) && (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) && (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) && (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) { - /* Converting the 1555 format in 5551 packed */ - DWORD i; - WORD *src = (WORD *) src_d->lpSurface, *dst; - - surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); - dst = (WORD *) surface; - if (src_d->dwFlags & DDSD_CKSRCBLT) { + DWORD i; + WORD *src = (WORD *) src_d->lpSurface, *dst; + + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + dst = (WORD *) surface; + for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { WORD color = *src++; *dst = (color & 0x7FFF) << 1; @@ -349,16 +370,14 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { *dst |= (color & 0x8000) >> 15; dst++; } + format = GL_RGBA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; } else { - for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { - WORD color = *src++; - *dst++ = (((color & 0x7FFF) << 1) | - ((color & 0x8000) >> 15)); - } + format = GL_BGRA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV; } - - format = GL_RGBA; - pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x7C00) && (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) && (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) && @@ -367,8 +386,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { DWORD i; WORD *src = (WORD *) src_d->lpSurface, *dst; - surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(WORD)); dst = (WORD *) surface; if (src_d->dwFlags & DDSD_CKSRCBLT) { @@ -388,6 +410,7 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { } format = GL_RGBA; + internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; } else { error = TRUE; @@ -403,8 +426,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { BYTE *src = (BYTE *) src_d->lpSurface; DWORD *dst; - surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); dst = (DWORD *) surface; for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { DWORD color = *((DWORD *) src) & 0x00FFFFFF; @@ -416,9 +442,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { dst++; } format = GL_RGBA; + internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_INT_8_8_8_8; } else { format = GL_BGR; + internal_format = GL_RGB; pixel_format = GL_UNSIGNED_BYTE; } } else { @@ -434,8 +462,12 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { DWORD i; DWORD *src = (DWORD *) src_d->lpSurface, *dst; - surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + dst = (DWORD *) surface; for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { DWORD color = *src++; @@ -447,19 +479,22 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { } } format = GL_RGBA; + internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_INT_8_8_8_8; } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) && (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xFF000000)) { - /* Convert from ARGB (Windows' format) to RGBA. - Note: need to check for GL extensions handling ARGB instead of always converting */ - DWORD i; - DWORD *src = (DWORD *) src_d->lpSurface, *dst; - - surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); - dst = (DWORD *) surface; if (src_d->dwFlags & DDSD_CKSRCBLT) { + DWORD i; + DWORD *src = (DWORD *) src_d->lpSurface, *dst; + + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + + dst = (DWORD *) surface; for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { DWORD color = *src++; *dst = (color & 0x00FFFFFF) << 8; @@ -468,16 +503,14 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { *dst |= (color & 0xFF000000) >> 24; dst++; } + format = GL_RGBA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_INT_8_8_8_8; } else { - for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { - DWORD color = *src++; - *dst = (color & 0x00FFFFFF) << 8; - *dst |= (color & 0xFF000000) >> 24; - dst++; - } + format = GL_BGRA; + internal_format = GL_RGBA; + pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV; } - format = GL_RGBA; - pixel_format = GL_UNSIGNED_INT_8_8_8_8; } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) && @@ -486,7 +519,10 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { DWORD i; DWORD *src = (DWORD *) src_d->lpSurface, *dst; - surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + if (glThis->surface_ptr != NULL) + surface = glThis->surface_ptr; + else + surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); dst = (DWORD *) surface; if (src_d->dwFlags & DDSD_CKSRCBLT) { @@ -504,6 +540,7 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { } } format = GL_RGBA; + internal_format = GL_RGBA; pixel_format = GL_UNSIGNED_INT_8_8_8_8; } else { error = TRUE; @@ -519,7 +556,7 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { if (gl_surf_ptr->initial_upload_done == FALSE) { glTexImage2D(GL_TEXTURE_2D, surf_ptr->mipmap_level, - format, + internal_format, src_d->dwWidth, src_d->dwHeight, 0, format, @@ -537,7 +574,9 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This) { } gl_surf_ptr->dirty_flag = FALSE; - if (surface) HeapFree(GetProcessHeap(), 0, surface); + /* And store the surface pointer for future reuse.. */ + if (surface) + glThis->surface_ptr = surface; } else if (error == TRUE) { if (ERR_ON(ddraw)) { ERR(" unsupported pixel format for textures : \n"); @@ -649,6 +688,9 @@ gltex_final_release(IDirectDrawSurfaceImpl *This) glDeleteTextures(1, &(glThis->tex_name)); LEAVE_GL(); + if (glThis->surface_ptr != NULL) + HeapFree(GetProcessHeap(), 0, glThis->surface_ptr); + /* And if this texture was the current one, remove it at the device level */ if (This->d3ddevice != NULL) for (i = 0; i < MAX_TEXTURES; i++) diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h index c8e1b953725..973308a286c 100644 --- a/dlls/ddraw/mesa_private.h +++ b/dlls/ddraw/mesa_private.h @@ -81,6 +81,9 @@ typedef struct IDirect3DTextureGLImpl BOOLEAN initial_upload_done; BOOLEAN dirty_flag; + /* Surface optimization */ + void *surface_ptr; + /* This is for now used to override 'standard' surface stuff to be as transparent as possible */ void (*final_release)(struct IDirectDrawSurfaceImpl *This); void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);