[D3D] Some texturing code refactoring

Lionel Ulmer lionel.ulmer at free.fr
Thu May 29 15:15:12 CDT 2003


No real new features, just some rewrite of the code to be able to use it
in the Lock / Unlock code and in my soon to be sent Blt patch.

It should fix one bug too (Christian, could you test if you still have the
'black border' problem in Motoracer 2 ?).

This seems to not regress anything (but well, did only some tests using Mesa
and the 4 apps I have installed on this laptop :-) ).

Changelog:
 - refactoring of the texture upload code

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- dlls/ddraw_CVS/d3dtexture.c	2003-05-26 11:07:28.000000000 +0200
+++ dlls/ddraw/d3dtexture.c	2003-05-29 21:25:51.000000000 +0200
@@ -84,500 +84,7 @@
  */
 
 HRESULT
-gltex_flush_texture_memory_to_GL(IDirectDrawSurfaceImpl *surf_ptr) {
-#if 0
-    static BOOL color_table_queried = FALSE;
-#endif
-    static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
-				      GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
-    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;
-    BOOL upload_done = FALSE;
-    BOOL error = FALSE;
-	
-    if (gl_surf_ptr->dirty_flag != SURFACE_MEMORY_DIRTY) {
-        TRACE("   - level %d already uploaded.\n", surf_ptr->mipmap_level);
-    } else {
-        TRACE("   - uploading texture level %d (initial done = %d).\n",
-	      surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done);
-	
-	/* Texture snooping for the curious :-) */
-	snoop_texture(surf_ptr);
-	
-	if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
-	    /* ****************
-	       Paletted Texture
-	       **************** */
-	    IDirectDrawPaletteImpl* pal = surf_ptr->palette;
-	    BYTE table[256][4];
-	    int i;
-	    
-#if 0
-	    if (color_table_queried == FALSE) {
-	        ptr_ColorTableEXT =
-		  ((Mesa_DeviceCapabilities *) ((x11_dd_private *) surf_ptr->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
-	    }
-#endif
-	    
-	    if (pal == NULL) {
-	        /* Upload a black texture. The real one will be uploaded on palette change */
-	        WARN("Palettized texture Loading with a NULL palette !\n");
-		memset(table, 0, 256 * 4);
-	    } else {
-	        /* Get the surface's palette */
-	        for (i = 0; i < 256; i++) {
-		    table[i][0] = pal->palents[i].peRed;
-		    table[i][1] = pal->palents[i].peGreen;
-		    table[i][2] = pal->palents[i].peBlue;
-		    if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
-			(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
-			(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-		        /* We should maybe here put a more 'neutral' color than the standard bright purple
-			   one often used by application to prevent the nice purple borders when bi-linear
-			   filtering is on */
-		        table[i][3] = 0x00;
-		    else
-		        table[i][3] = 0xFF;
-		}
-	    }
-
-	    if (ptr_ColorTableEXT != NULL) {
-	        /* use Paletted Texture Extension */
-	        ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
-				  GL_RGBA,          /* internal format */
-				  256,              /* table size */
-				  GL_RGBA,          /* table format */
-				  GL_UNSIGNED_BYTE, /* table type */
-				  table);           /* the color table */
-		
-		glTexImage2D(GL_TEXTURE_2D,       /* target */
-			     surf_ptr->mipmap_level, /* level */
-			     GL_COLOR_INDEX8_EXT, /* internal format */
-			     src_d->dwWidth, src_d->dwHeight, /* width, height */
-			     0,                   /* border */
-			     GL_COLOR_INDEX,      /* texture format */
-			     GL_UNSIGNED_BYTE,    /* texture type */
-			     src_d->lpSurface); /* the texture */
-		
-		upload_done = TRUE;
-	    } else {
-	        DWORD i;
-		BYTE *src = (BYTE *) src_d->lpSurface, *dst;
-		
-		if (gl_surf_ptr->surface_ptr != NULL)
-		    surface = gl_surf_ptr->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++) {
-		    BYTE color = *src++;
-		    *dst++ = table[color][0];
-		    *dst++ = table[color][1];
-		    *dst++ = table[color][2];
-		    *dst++ = table[color][3];
-		}
-		
-		format = GL_RGBA;
-		internal_format = GL_RGBA;
-		pixel_format = GL_UNSIGNED_BYTE;
-	    }
-	} else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
-	    /* ************
-	       RGB Textures
-	       ************ */
-	    if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
-	        if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xE0) &&
-		    (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x1C) &&
-		    (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x03)) {
-		    /* **********************
-		       GL_UNSIGNED_BYTE_3_3_2
-		       ********************** */
-		    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-		        /* This texture format will never be used.. So do not care about color keying
-			   up until the point in time it will be needed :-) */
-		        error = TRUE;
-		    } else {
-		        format = GL_RGB;
-			internal_format = GL_RGB;
-			pixel_format = GL_UNSIGNED_BYTE_3_3_2;
-		    }
-		} else {
-		    error = TRUE;
-		}
-	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
-	        if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF800) &&
-		    (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x07E0) &&
-		    (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
-		    (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
-		    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-		        /* Converting the 565 format in 5551 packed to emulate color-keying.
-			   
-			   Note : in all these conversion, it would be best to average the averaging
-			          pixels to get the color of the pixel that will be color-keyed to
-				  prevent 'color bleeding'. This will be done later on if ever it is
-				  too visible.
-				      
-			   Note2: when using color-keying + alpha, are the alpha bits part of the
-			          color-space or not ?
-			*/
-		        DWORD i;
-			WORD *src = (WORD *) src_d->lpSurface, *dst;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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 & 0xFFC0) | ((color & 0x1F) << 1));
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-			        *dst |= 0x0001;
-			    dst++;
-			}
-			
-			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) &&
-			   (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x07C0) &&
-			   (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x003E) &&
-			   (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) {
-		    format = GL_RGBA;
-		    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;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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 & 0xFFFE;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= color & 0x0001;
-			    dst++;
-			}
-		    }
-		} else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF000) &&
-			   (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0F00) &&
-			   (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x00F0) &&
-			   (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) {
-		    format = GL_RGBA;
-		    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;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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 & 0xFFF0;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= color & 0x000F;
-			    dst++;
-			}
-		    }
-		} else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x0F00) &&
-			   (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x00F0) &&
-			   (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000F) &&
-			   (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) {
-		    /* Move the four Alpha bits... */
-		    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-			DWORD i;
-			WORD *src = (WORD *) src_d->lpSurface, *dst;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= (color & 0xF000) >> 12;
-			    dst++;
-			}
-			format = GL_RGBA;
-			internal_format = GL_RGBA;
-			pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
-		    } else {
-			format = GL_BGRA;
-			internal_format = GL_RGBA;
-			pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV;
-		    }
-		} 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)) {
-		    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-			DWORD i;
-			WORD *src = (WORD *) src_d->lpSurface, *dst;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= (color & 0x8000) >> 15;
-			    dst++;
-			}
-			format = GL_RGBA;
-			internal_format = GL_RGBA;
-			pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
-		    } else {
-			format = GL_BGRA;
-			internal_format = GL_RGBA;
-			pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV;
-		    }
-		} 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 == 0x0000)) {
-		    /* Converting the 0555 format in 5551 packed */
-		    DWORD i;
-		    WORD *src = (WORD *) src_d->lpSurface, *dst;
-		    
-		    if (gl_surf_ptr->surface_ptr != NULL)
-			surface = gl_surf_ptr->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) {
-			for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-			    WORD color = *src++;
-			    *dst = (color & 0x7FFF) << 1;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= 0x0001;
-			    dst++;
-			}
-		    } else {
-			for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-			    WORD color = *src++;
-			    *dst++ = ((color & 0x7FFF) << 1) | 0x0001;
-			}
-		    }
-		    
-		    format = GL_RGBA;
-		    internal_format = GL_RGBA;
-		    pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
-		} else {
-		    error = TRUE;
-		}
-	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
-		if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
-		    (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
-		    (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
-		    (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
-		    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-			/* This is a pain :-) */
-			DWORD i;
-			BYTE *src = (BYTE *) src_d->lpSurface;
-			DWORD *dst;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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;
-			    src += 3;
-			    *dst = *src++ << 8;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= 0xFF;
-			    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 {
-		    error = TRUE;
-		}
-	    } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
-		if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xFF000000) &&
-		    (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x00FF0000) &&
-		    (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x0000FF00) &&
-		    (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000000FF)) {
-		    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-			/* Just use the alpha component to handle color-keying... */
-			DWORD i;
-			DWORD *src = (DWORD *) src_d->lpSurface, *dst;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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 & 0xFFFFFF00;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= color & 0x000000FF;
-			    dst++;
-			}
-		    }
-		    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)) {
-		    if (src_d->dwFlags & DDSD_CKSRCBLT) {
-			DWORD i;
-			DWORD *src = (DWORD *) src_d->lpSurface, *dst;
-			
-			if (gl_surf_ptr->surface_ptr != NULL)
-			    surface = gl_surf_ptr->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;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= (color & 0xFF000000) >> 24;
-			    dst++;
-			}
-			format = GL_RGBA;
-			internal_format = GL_RGBA;
-			pixel_format = GL_UNSIGNED_INT_8_8_8_8;
-		    } else {
-			format = GL_BGRA;
-			internal_format = GL_RGBA;
-			pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV;
-		    }
-		} 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 == 0x00000000)) {
-		    /* Just add an alpha component and handle color-keying... */
-		    DWORD i;
-		    DWORD *src = (DWORD *) src_d->lpSurface, *dst;
-		    
-		    if (gl_surf_ptr->surface_ptr != NULL)
-			surface = gl_surf_ptr->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) {
-			for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-			    DWORD color = *src++;
-			    *dst = color << 8;
-			    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
-				(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-				*dst |= 0xFF;
-			    dst++;
-			}
-		    } else {
-			for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
-			    *dst++ = (*src++ << 8) | 0xFF;
-			}
-		    }
-		    format = GL_RGBA;
-		    internal_format = GL_RGBA;
-		    pixel_format = GL_UNSIGNED_INT_8_8_8_8;
-		} else {
-		    error = TRUE;
-		}
-	    } else {
-		error = TRUE;
-	    }
-	} else {
-	    error = TRUE;
-	} 
-	
-	if ((upload_done == FALSE) && (error == FALSE)) {
-	    if (gl_surf_ptr->initial_upload_done == FALSE) {
-		glTexImage2D(GL_TEXTURE_2D,
-			     surf_ptr->mipmap_level,
-			     internal_format,
-			     src_d->dwWidth, src_d->dwHeight,
-			     0,
-			     format,
-			     pixel_format,
-			     surface == NULL ? src_d->lpSurface : surface);
-		gl_surf_ptr->initial_upload_done = TRUE;
-	    } else {
-		glTexSubImage2D(GL_TEXTURE_2D,
-				surf_ptr->mipmap_level,
-				0, 0,
-				src_d->dwWidth, src_d->dwHeight,
-				format,
-				pixel_format,
-				surface == NULL ? src_d->lpSurface : surface);
-	    }
-	    gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
-	    
-	    /* And store the surface pointer for future reuse.. */
-	    if (surface)
-		gl_surf_ptr->surface_ptr = surface;
-	} else if (error == TRUE) {
-	    if (ERR_ON(ddraw)) {
-		ERR("  unsupported pixel format for textures : \n");
-		DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat);
-	    }
-	}
-    }
-    
-    return DD_OK;
-}
-
-HRESULT
-gltex_flush_texture_GL_to_memory(IDirectDrawSurfaceImpl *surf_ptr) {
+gltex_download_texture(IDirectDrawSurfaceImpl *surf_ptr) {
     IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
 
     FIXME("This is not supported yet... Expect some graphical glitches !!!\n");
@@ -589,28 +96,43 @@
 }
 
 HRESULT
-gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
-    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
-    IDirectDrawSurfaceImpl *surf_ptr;
-    GLuint tex_name = glThis->tex_name;
+gltex_upload_texture(IDirectDrawSurfaceImpl *surf_ptr) {
+    IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
+    GLuint tex_name = gl_surf_ptr->tex_name;
     
     TRACE(" activating OpenGL texture id %d.\n", tex_name);
     glBindTexture(GL_TEXTURE_2D, tex_name);
 
-    if (This->mipmap_level != 0) {
-        WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", This->mipmap_level);
+    if (surf_ptr->mipmap_level != 0) {
+        WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", surf_ptr->mipmap_level);
     }
     
-    surf_ptr = This;
     while (surf_ptr != NULL) {
-	gltex_flush_texture_memory_to_GL(surf_ptr);
+        IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
+	
+	if (gl_surf_ptr->dirty_flag != SURFACE_MEMORY_DIRTY) {
+            TRACE("   - level %d already uploaded.\n", surf_ptr->mipmap_level);
+	} else {
+	    TRACE("   - uploading texture level %d (initial done = %d).\n",
+		  surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done);
+	    
+	    /* Texture snooping for the curious :-) */
+	    snoop_texture(surf_ptr);
+
+	    if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format),
+						  gl_surf_ptr->initial_upload_done == FALSE, TRUE) == D3D_OK) {
+	        upload_surface_to_tex_memory(NULL, &(gl_surf_ptr->surface_ptr));
+		upload_surface_to_tex_memory_release();
+		gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
+	    }
+	}
 	
 	if (surf_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) {
 	    surf_ptr = get_sub_mimaplevel(surf_ptr);
 	} else {
 	    surf_ptr = NULL;
 	}
-      }
+    }
 
     return DD_OK;
 }
@@ -636,7 +158,7 @@
 	ENTER_GL();
 	glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
 	glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
-	gltex_flush_texture_GL_to_memory(This);
+	gltex_download_texture(This);
 	glBindTexture(GL_TEXTURE_2D, cur_tex);
 	LEAVE_GL();
     }
@@ -708,13 +230,27 @@
 		!((dstx == 0) && (dsty == 0) &&
 		  (width == surf_ptr->surface_desc.dwWidth) && (height == surf_ptr->surface_desc.dwHeight))) {
 		/* If not 'full size' and the surface is dirty, first flush it to GL before doing the copy. */
-		gltex_flush_texture_memory_to_GL(surf_ptr);
+	        if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format),
+						      gl_surf_ptr->initial_upload_done == FALSE, TRUE) != D3D_OK) {
+		    upload_surface_to_tex_memory(NULL, &(gl_surf_ptr->surface_ptr));
+		    upload_surface_to_tex_memory_release();
+		    gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
+		} else {
+		    return DDERR_INVALIDPARAMS;
+		}
 	    }
 
 	    /* This is a hack and would need some clean-up :-) */
 	    if (gl_surf_ptr->initial_upload_done == FALSE) {
 		gl_surf_ptr->dirty_flag = SURFACE_MEMORY_DIRTY;
-		gltex_flush_texture_memory_to_GL(surf_ptr);
+		if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format),
+						       gl_surf_ptr->initial_upload_done == FALSE, TRUE) != D3D_OK) {
+		    upload_surface_to_tex_memory(NULL, &(gl_surf_ptr->surface_ptr));
+		    upload_surface_to_tex_memory_release();
+		    gl_surf_ptr->dirty_flag = SURFACE_MEMORY;
+		} else {
+		    return DDERR_INVALIDPARAMS;
+		}
 	    }
 	    
 	    if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0)
@@ -807,7 +343,7 @@
 	ENTER_GL();
 	glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
 	glBindTexture(GL_TEXTURE_2D, glThis->tex_name);
-	gltex_flush_texture_GL_to_memory(This);
+	gltex_download_texture(This);
 	glBindTexture(GL_TEXTURE_2D, cur_tex);
 	LEAVE_GL();
     }
--- dlls/ddraw_CVS/mesa.c	2003-05-26 14:51:52.000000000 +0200
+++ dlls/ddraw/mesa.c	2003-05-29 21:28:21.000000000 +0200
@@ -20,6 +20,8 @@
 
 #include "config.h"
 
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
 #include "windef.h"
 #include "objbase.h"
 #include "ddraw.h"
@@ -543,3 +545,557 @@
 	if (lpStateBlock->set_flags.render_state[i])
             set_render_state(This, i + 1, lpStateBlock);
 }
+
+
+/* Texture management code.
+
+    - upload_surface_to_tex_memory_init initialize the code and computes the GL formats 
+      according to the surface description.
+
+    - upload_surface_to_tex_memory does the real upload. If one buffer is split over
+      multiple textures, this can be called multiple times after the '_init' call. 'rect'
+      can be NULL if the whole buffer needs to be upload.
+
+    - upload_surface_to_tex_memory_release does the clean-up.
+
+   These functions are called in the following cases :
+    - texture management (ie to upload a D3D texture to GL when it changes).
+    - flush of the 'in-memory' frame buffer to the GL frame buffer using the texture
+      engine.
+    - use of the texture engine to simulate Blits to the 3D Device.
+*/
+typedef enum {
+    NO_CONVERSION,
+    CONVERT_PALETTED,
+    CONVERT_CK_565,
+    CONVERT_CK_5551,
+    CONVERT_CK_4444,
+    CONVERT_CK_4444_ARGB,
+    CONVERT_CK_1555,
+    CONVERT_555,
+    CONVERT_CK_RGB24,
+    CONVERT_CK_8888,
+    CONVERT_CK_8888_ARGB,
+    CONVERT_RGB32_888
+} CONVERT_TYPES;
+
+/* Note : we suppose that all the code calling this is protected by the GL lock... Otherwise bad things
+   may happen :-) */
+static GLenum current_format;
+static GLenum current_pixel_format;
+static CONVERT_TYPES convert_type;
+static IDirectDrawSurfaceImpl *current_surface;
+static GLuint current_level;
+
+HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLuint level, GLenum *current_internal_format,
+					  BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck)
+{
+    const DDPIXELFORMAT * const src_pf = &(surf_ptr->surface_desc.u4.ddpfPixelFormat);
+    BOOL error = FALSE;
+    BOOL colorkey_active = need_alpha_ck && (surf_ptr->surface_desc.dwFlags & DDSD_CKSRCBLT);
+    GLenum internal_format = GL_LUMINANCE; /* A bogus value to be sure to have a nice Mesa warning :-) */
+
+    current_surface = surf_ptr;
+    current_level = level;
+
+    if (src_pf->dwFlags & DDPF_PALETTEINDEXED8) {
+	/* ****************
+	   Paletted Texture
+	   **************** */
+	current_format = GL_RGBA;
+	internal_format = GL_RGBA;
+	current_pixel_format = GL_UNSIGNED_BYTE;
+	convert_type = CONVERT_PALETTED;
+    } else if (src_pf->dwFlags & DDPF_RGB) {
+	/* ************
+	   RGB Textures
+	   ************ */
+	if (src_pf->u1.dwRGBBitCount == 8) {
+	    if ((src_pf->u2.dwRBitMask == 0xE0) &&
+		(src_pf->u3.dwGBitMask == 0x1C) &&
+		(src_pf->u4.dwBBitMask == 0x03)) {
+		/* **********************
+		   GL_UNSIGNED_BYTE_3_3_2
+		   ********************** */
+		if (colorkey_active) {
+		    /* This texture format will never be used.. So do not care about color keying
+		       up until the point in time it will be needed :-) */
+		    FIXME(" ColorKeying not supported in the RGB 332 format !");
+		}
+		current_format = GL_RGB;
+		internal_format = GL_RGB;
+		current_pixel_format = GL_UNSIGNED_BYTE_3_3_2;
+		convert_type = NO_CONVERSION;
+	    } else {
+		error = TRUE;
+	    }
+	} else if (src_pf->u1.dwRGBBitCount == 16) {
+	    if ((src_pf->u2.dwRBitMask ==        0xF800) &&
+		(src_pf->u3.dwGBitMask ==        0x07E0) &&
+		(src_pf->u4.dwBBitMask ==        0x001F) &&
+		(src_pf->u5.dwRGBAlphaBitMask == 0x0000)) {
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_565;
+		    current_format = GL_RGBA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
+		} else {
+		    convert_type = NO_CONVERSION;
+		    current_format = GL_RGB;
+		    internal_format = GL_RGB;
+		    current_pixel_format = GL_UNSIGNED_SHORT_5_6_5;
+		}
+	    } else if ((src_pf->u2.dwRBitMask ==        0xF800) &&
+		       (src_pf->u3.dwGBitMask ==        0x07C0) &&
+		       (src_pf->u4.dwBBitMask ==        0x003E) &&
+		       (src_pf->u5.dwRGBAlphaBitMask == 0x0001)) {
+		current_format = GL_RGBA;
+		internal_format = GL_RGBA;
+		current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_5551;
+		} else {
+		    convert_type = NO_CONVERSION;
+		}
+	    } else if ((src_pf->u2.dwRBitMask ==        0xF000) &&
+		       (src_pf->u3.dwGBitMask ==        0x0F00) &&
+		       (src_pf->u4.dwBBitMask ==        0x00F0) &&
+		       (src_pf->u5.dwRGBAlphaBitMask == 0x000F)) {
+		current_format = GL_RGBA;
+		internal_format = GL_RGBA;
+		current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_4444;
+		} else {
+		    convert_type = NO_CONVERSION;
+		}
+	    } else if ((src_pf->u2.dwRBitMask ==        0x0F00) &&
+		       (src_pf->u3.dwGBitMask ==        0x00F0) &&
+		       (src_pf->u4.dwBBitMask ==        0x000F) &&
+		       (src_pf->u5.dwRGBAlphaBitMask == 0xF000)) {
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_4444_ARGB;
+		    current_format = GL_RGBA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;
+		} else {
+		    convert_type = NO_CONVERSION;
+		    current_format = GL_BGRA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+		}
+	    } else if ((src_pf->u2.dwRBitMask ==        0x7C00) &&
+		       (src_pf->u3.dwGBitMask ==        0x03E0) &&
+		       (src_pf->u4.dwBBitMask ==        0x001F) &&
+		       (src_pf->u5.dwRGBAlphaBitMask == 0x8000)) {
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_1555;
+		    current_format = GL_RGBA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
+		} else {
+		    convert_type = NO_CONVERSION;
+		    current_format = GL_BGRA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV;
+		}
+	    } else if ((src_pf->u2.dwRBitMask ==        0x7C00) &&
+		       (src_pf->u3.dwGBitMask ==        0x03E0) &&
+		       (src_pf->u4.dwBBitMask ==        0x001F) &&
+		       (src_pf->u5.dwRGBAlphaBitMask == 0x0000)) {
+		convert_type = CONVERT_555;
+		current_format = GL_RGBA;
+		internal_format = GL_RGBA;
+		current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
+	    } else {
+		error = TRUE;
+	    }
+	} else if (src_pf->u1.dwRGBBitCount == 24) {
+	    if ((src_pf->u2.dwRBitMask ==        0x00FF0000) &&
+		(src_pf->u3.dwGBitMask ==        0x0000FF00) &&
+		(src_pf->u4.dwBBitMask ==        0x000000FF) &&
+		(src_pf->u5.dwRGBAlphaBitMask == 0x00000000)) {
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_RGB24;
+		    current_format = GL_RGBA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+		} else {
+		    convert_type = NO_CONVERSION;
+		    current_format = GL_BGR;
+		    internal_format = GL_RGB;
+		    current_pixel_format = GL_UNSIGNED_BYTE;
+		}
+	    } else {
+		error = TRUE;
+	    }
+	} else if (src_pf->u1.dwRGBBitCount == 32) {
+	    if ((src_pf->u2.dwRBitMask ==        0xFF000000) &&
+		(src_pf->u3.dwGBitMask ==        0x00FF0000) &&
+		(src_pf->u4.dwBBitMask ==        0x0000FF00) &&
+		(src_pf->u5.dwRGBAlphaBitMask == 0x000000FF)) {
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_8888;
+		} else {
+		    convert_type = NO_CONVERSION;
+		}
+		current_format = GL_RGBA;
+		internal_format = GL_RGBA;
+		current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+	    } else if ((src_pf->u2.dwRBitMask ==        0x00FF0000) &&
+		       (src_pf->u3.dwGBitMask ==        0x0000FF00) &&
+		       (src_pf->u4.dwBBitMask ==        0x000000FF) &&
+		       (src_pf->u5.dwRGBAlphaBitMask == 0xFF000000)) {
+		if (colorkey_active) {
+		    convert_type = CONVERT_CK_8888_ARGB;
+		    current_format = GL_RGBA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+		} else {
+		    convert_type = NO_CONVERSION;
+		    current_format = GL_BGRA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV;
+		}
+	    } else if ((src_pf->u2.dwRBitMask ==        0x00FF0000) &&
+		       (src_pf->u3.dwGBitMask ==        0x0000FF00) &&
+		       (src_pf->u4.dwBBitMask ==        0x000000FF) &&
+		       (src_pf->u5.dwRGBAlphaBitMask == 0x00000000)) {
+		if (need_alpha_ck) {
+		    convert_type = CONVERT_RGB32_888;
+		    current_format = GL_RGBA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_INT_8_8_8_8;
+		} else {
+		    convert_type = NO_CONVERSION;
+		    current_format = GL_BGRA;
+		    internal_format = GL_RGBA;
+		    current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV;
+		}
+	    } else {
+		error = TRUE;
+	    }
+	} else {
+	    error = TRUE;
+	}
+    } else {
+	error = TRUE;
+    } 
+
+    if (error == TRUE) {
+	if (ERR_ON(ddraw)) {
+	    ERR("  unsupported pixel format for textures : \n");
+	    DDRAW_dump_pixelformat(src_pf);
+	}
+	return DDERR_INVALIDPIXELFORMAT;
+    } else {
+	if ((need_to_alloc) ||
+	    (internal_format != *current_internal_format)) {
+	    glTexImage2D(GL_TEXTURE_2D, level, internal_format,
+			 surf_ptr->surface_desc.dwWidth, surf_ptr->surface_desc.dwHeight, 0,
+			 current_format, current_pixel_format, NULL);
+	    *current_internal_format = internal_format;
+	}
+    }
+
+    return DD_OK;
+}
+
+HRESULT upload_surface_to_tex_memory(RECT *rect, void **temp_buffer)
+{
+    const DDSURFACEDESC * const src_d = (DDSURFACEDESC *)&(current_surface->surface_desc);
+    void *surf_buffer = NULL;
+    
+    switch (convert_type) {
+        case CONVERT_PALETTED: {
+	    IDirectDrawPaletteImpl* pal = current_surface->palette;
+	    BYTE table[256][4];
+	    int i;
+	    BYTE *src = (BYTE *) src_d->lpSurface, *dst;
+	    	    
+	    if (pal == NULL) {
+		/* Upload a black texture. The real one will be uploaded on palette change */
+		WARN("Palettized texture Loading with a NULL palette !\n");
+		memset(table, 0, 256 * 4);
+	    } else {
+		/* Get the surface's palette */
+		for (i = 0; i < 256; i++) {
+		    table[i][0] = pal->palents[i].peRed;
+		    table[i][1] = pal->palents[i].peGreen;
+		    table[i][2] = pal->palents[i].peBlue;
+		    if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
+			(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
+			(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+			/* We should maybe here put a more 'neutral' color than the standard bright purple
+			   one often used by application to prevent the nice purple borders when bi-linear
+			   filtering is on */
+			table[i][3] = 0x00;
+		    else
+			table[i][3] = 0xFF;
+		}
+	    }
+	    
+	    if (*temp_buffer == NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
+					 src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+	    dst = (BYTE *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		BYTE color = *src++;
+		*dst++ = table[color][0];
+		*dst++ = table[color][1];
+		*dst++ = table[color][2];
+		*dst++ = table[color][3];
+	    }
+	} break;
+
+        case CONVERT_CK_565: {
+	    /* Converting the 565 format in 5551 packed to emulate color-keying.
+	       
+	       Note : in all these conversion, it would be best to average the averaging
+	              pixels to get the color of the pixel that will be color-keyed to
+		      prevent 'color bleeding'. This will be done later on if ever it is
+		      too visible.
+		      
+	       Note2: when using color-keying + alpha, are the alpha bits part of the
+	              color-space or not ?
+	    */
+	    DWORD i;
+	    WORD *src = (WORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+	    dst = (WORD *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		WORD color = *src++;
+		*dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= 0x0001;
+		dst++;
+	    }
+	} break;
+	
+        case CONVERT_CK_5551: {
+	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
+	    DWORD i;
+	    WORD *src = (WORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+	    dst = (WORD *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		WORD color = *src++;
+		*dst = color & 0xFFFE;
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= color & 0x0001;
+		dst++;
+	    }
+	} break;
+	
+        case CONVERT_CK_4444: {
+	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
+	    DWORD i;
+	    WORD *src = (WORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+	    dst = (WORD *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		WORD color = *src++;
+		*dst = color & 0xFFF0;
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= color & 0x000F;
+		dst++;
+	    }
+	} break;
+	
+        case CONVERT_CK_4444_ARGB: {
+	    /* Move the four Alpha bits... */
+	    DWORD i;
+	    WORD *src = (WORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+	    dst = (WORD *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		WORD color = *src++;
+		*dst = (color & 0x0FFF) << 4;
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= (color & 0xF000) >> 12;
+		dst++;
+	    }
+	} break;
+	
+        case CONVERT_CK_1555: {
+	    DWORD i;
+	    WORD *src = (WORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+	    dst = (WORD *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		WORD color = *src++;
+		*dst = (color & 0x7FFF) << 1;
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= (color & 0x8000) >> 15;
+		dst++;
+	    }
+	} break;
+	
+        case CONVERT_555: {
+	    /* Converting the 0555 format in 5551 packed */
+	    DWORD i;
+	    WORD *src = (WORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+	    dst = (WORD *) *temp_buffer;
+	    
+	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    WORD color = *src++;
+		    *dst = (color & 0x7FFF) << 1;
+		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+			*dst |= 0x0001;
+		    dst++;
+		}
+	    } else {
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    WORD color = *src++;
+		    *dst++ = ((color & 0x7FFF) << 1) | 0x0001;
+		}
+	    }
+	    
+	} break;
+	
+        case CONVERT_CK_RGB24: {
+	    /* This is a pain :-) */
+	    DWORD i;
+	    BYTE *src = (BYTE *) src_d->lpSurface;
+	    DWORD *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
+	    dst = (DWORD *) *temp_buffer;
+
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		DWORD color = *((DWORD *) src) & 0x00FFFFFF;
+		src += 3;
+		*dst = *src++ << 8;
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= 0xFF;
+		dst++;
+	    }
+	} break;
+
+        case CONVERT_CK_8888: {
+	    /* Just use the alpha component to handle color-keying... */
+	    DWORD i;
+	    DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));	    
+	    dst = (DWORD *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		DWORD color = *src++;
+		*dst = color & 0xFFFFFF00;
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= color & 0x000000FF;
+		dst++;
+	    }
+	} break;
+	
+        case CONVERT_CK_8888_ARGB: {
+	    DWORD i;
+	    DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));	    
+	    dst = (DWORD *) *temp_buffer;
+	    
+	    for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		DWORD color = *src++;
+		*dst = (color & 0x00FFFFFF) << 8;
+		if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+		    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    *dst |= (color & 0xFF000000) >> 24;
+		dst++;
+	    }
+	} break;
+	
+        case CONVERT_RGB32_888: {
+	    /* Just add an alpha component and handle color-keying... */
+	    DWORD i;
+	    DWORD *src = (DWORD *) src_d->lpSurface, *dst;
+	    
+	    if (*temp_buffer != NULL)
+		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+					 src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));	    
+	    dst = (DWORD *) *temp_buffer;
+	    
+	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    DWORD color = *src++;
+		    *dst = color << 8;
+		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
+			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+			*dst |= 0xFF;
+		    dst++;
+		}
+	    } else {
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    *dst++ = (*src++ << 8) | 0xFF;
+		}
+	    }
+	} break;
+
+        case NO_CONVERSION:
+	    /* Nothing to do here as the name suggests... This just prevents a compiler warning */
+	    surf_buffer = src_d->lpSurface;
+	    break;
+    }
+
+    if (convert_type != NO_CONVERSION) {
+	surf_buffer = *temp_buffer;
+    }
+    
+    glTexSubImage2D(GL_TEXTURE_2D,
+		    current_level,
+		    0, 0,
+		    src_d->dwWidth, src_d->dwHeight,
+		    current_format,
+		    current_pixel_format,
+		    surf_buffer);
+
+    return DD_OK;
+}
+
+HRESULT upload_surface_to_tex_memory_release(void)
+{
+    current_surface = NULL;
+
+    return DD_OK;
+}
--- dlls/ddraw_CVS/mesa_private.h	2003-05-26 10:05:23.000000000 +0200
+++ dlls/ddraw/mesa_private.h	2003-05-29 21:24:25.000000000 +0200
@@ -70,6 +70,9 @@
 
     /* Surface optimization */
     void *surface_ptr;
+
+    /* Used to detect a change in internal format when going from non-CK texture to CK-ed texture */
+    GLenum current_internal_format;
     
     /* This is for now used to override 'standard' surface stuff to be as transparent as possible */
     void (*final_release)(struct IDirectDrawSurfaceImpl *This);
@@ -143,6 +146,12 @@
 extern void get_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK* lpStateBlock);
 extern void apply_render_state(IDirect3DDeviceImpl* This, STATEBLOCK* lpStateBlock);
 
+/* Memory to texture conversion code. Split in three functions to do some optimizations. */
+extern HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surface, GLuint level, GLenum *prev_internal_format,
+						 BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck);
+extern HRESULT upload_surface_to_tex_memory(RECT *rect, void **temp_buffer);
+extern HRESULT upload_surface_to_tex_memory_release(void);
+
 /* This structure contains all the function pointers to OpenGL extensions
    that are used by Wine */
 typedef struct {


More information about the wine-patches mailing list