/* Direct3D Common functions
 * Copyright (c) 1998 Lionel ULMER
 *
 * This file contains all MESA common code
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "objbase.h"
#include "ddraw.h"
#include "d3d.h"
#include "wine/debug.h"

#include "mesa_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

GLenum convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState)
{
    switch (dwRenderState) {
        case D3DCMP_NEVER: return GL_NEVER;
	case D3DCMP_LESS: return GL_LESS;
	case D3DCMP_EQUAL: return GL_EQUAL;
	case D3DCMP_LESSEQUAL: return GL_LEQUAL;
	case D3DCMP_GREATER: return GL_GREATER;
	case D3DCMP_NOTEQUAL: return GL_NOTEQUAL;
	case D3DCMP_GREATEREQUAL: return GL_GEQUAL;
	case D3DCMP_ALWAYS: return GL_ALWAYS;
	default: ERR("Unexpected compare type %d !\n", dwRenderState);
    }
    return GL_ALWAYS;
}

GLenum convert_D3D_stencilop_to_GL(D3DSTENCILOP dwRenderState)
{
    switch (dwRenderState) {
        case D3DSTENCILOP_KEEP: return GL_KEEP;
        case D3DSTENCILOP_ZERO: return GL_ZERO;
        case D3DSTENCILOP_REPLACE: return GL_REPLACE;
        case D3DSTENCILOP_INCRSAT: return GL_INCR;
        case D3DSTENCILOP_DECRSAT: return GL_DECR;
        case D3DSTENCILOP_INVERT: return GL_INVERT;
        case D3DSTENCILOP_INCR: WARN("D3DSTENCILOP_INCR not properly handled !\n"); return GL_INCR;
        case D3DSTENCILOP_DECR: WARN("D3DSTENCILOP_DECR not properly handled !\n"); return GL_DECR;
        default: ERR("Unexpected compare type %d !\n", dwRenderState);      
    }
    return GL_KEEP;
}

GLenum convert_D3D_blendop_to_GL(D3DBLEND dwRenderState)
{
    switch ((D3DBLEND) dwRenderState) {
        case D3DBLEND_ZERO: return GL_ZERO;
        case D3DBLEND_ONE: return GL_ONE;
	case D3DBLEND_SRCALPHA: return GL_SRC_ALPHA;
	case D3DBLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA;
	case D3DBLEND_DESTALPHA: return GL_DST_ALPHA;
	case D3DBLEND_INVDESTALPHA: return GL_ONE_MINUS_DST_ALPHA;
	case D3DBLEND_DESTCOLOR: return GL_DST_COLOR;
	case D3DBLEND_INVDESTCOLOR: return GL_ONE_MINUS_DST_COLOR;
	case D3DBLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE;
	case D3DBLEND_SRCCOLOR: return GL_SRC_COLOR;
	case D3DBLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR;
        default: ERR("Unhandled blend mode %d !\n", dwRenderState); return GL_ZERO;
    }
}

void set_render_state(IDirect3DDeviceImpl* This,
		      D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock)
{
    DWORD dwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
    IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This;
    
    TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);

    /* First, all the stipple patterns */
    if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) &&
	(dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) {
        ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType);
    } else {
        ENTER_GL();

	/* All others state variables */
	switch (dwRenderStateType) {
	    case D3DRENDERSTATE_TEXTUREHANDLE: {    /*  1 */
	        IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
		
		IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
					    0, 
					    ICOM_INTERFACE(tex, IDirectDrawSurface7));
	    } break;

	    case D3DRENDERSTATE_ANTIALIAS:        /*  2 */
	        if (dwRenderState)
		    ERR("D3DRENDERSTATE_ANTIALIAS not supported yet !\n");
	        break;
	      
	    case D3DRENDERSTATE_TEXTUREADDRESSU:  /* 44 */
	    case D3DRENDERSTATE_TEXTUREADDRESSV:  /* 45 */
	    case D3DRENDERSTATE_TEXTUREADDRESS: { /*  3 */
	        D3DTEXTURESTAGESTATETYPE d3dTexStageStateType;

		if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) d3dTexStageStateType = D3DTSS_ADDRESS;
		else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) d3dTexStageStateType = D3DTSS_ADDRESSU;
		else d3dTexStageStateType = D3DTSS_ADDRESSV;

		IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
						      0, d3dTexStageStateType,
						      dwRenderState);
	    } break;
	      
	    case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
	        if (dwRenderState)
		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
		else
		    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
	        break;

	    case D3DRENDERSTATE_WRAPU: /* 5 */
	    case D3DRENDERSTATE_WRAPV: /* 6 */
	    case D3DRENDERSTATE_WRAP0: /* 128 */
	    case D3DRENDERSTATE_WRAP1: /* 129 */
	    case D3DRENDERSTATE_WRAP2: /* 130 */
	    case D3DRENDERSTATE_WRAP3: /* 131 */
	    case D3DRENDERSTATE_WRAP4: /* 132 */
	    case D3DRENDERSTATE_WRAP5: /* 133 */
	    case D3DRENDERSTATE_WRAP6: /* 134 */
	    case D3DRENDERSTATE_WRAP7: /* 135 */
	        if (dwRenderState)
		    ERR("Texture WRAP modes unsupported by OpenGL.. Expect graphical glitches !\n");
	        break;

	    case D3DRENDERSTATE_ZENABLE:          /*  7 */
	        /* To investigate : in OpenGL, if we disable the depth test, the Z buffer will NOT be
		   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) {
		    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;

	    case D3DRENDERSTATE_FILLMODE:           /*  8 */
	        switch ((D3DFILLMODE) dwRenderState) {
		    case D3DFILL_POINT:
		        glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);        
			break;
		    case D3DFILL_WIREFRAME:
			glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
			break;
		    case D3DFILL_SOLID:
			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
			break;
		    default:
			ERR("Unhandled fill mode %ld !\n",dwRenderState);
		 }
	         break;

	    case D3DRENDERSTATE_SHADEMODE:          /*  9 */
	        switch ((D3DSHADEMODE) dwRenderState) {
		    case D3DSHADE_FLAT:
		        glShadeModel(GL_FLAT);
			break;
		    case D3DSHADE_GOURAUD:
			glShadeModel(GL_SMOOTH);
			break;
		    default:
			ERR("Unhandled shade mode %ld !\n",dwRenderState);
		}
	        break;

	    case D3DRENDERSTATE_ZWRITEENABLE:     /* 14 */
	        if ((dwRenderState != FALSE) && (glThis->depth_mask == FALSE))
		    glDepthMask(GL_TRUE);
		else if ((dwRenderState == FALSE) && (glThis->depth_mask != FALSE))
		    glDepthMask(GL_FALSE);
	        glThis->depth_mask = dwRenderState;
	        break;
	      
	    case D3DRENDERSTATE_ALPHATESTENABLE:  /* 15 */
	        if ((dwRenderState != 0) && (glThis->alpha_test == FALSE))
		    glEnable(GL_ALPHA_TEST);
	        else if ((dwRenderState == 0) && (glThis->alpha_test != FALSE))
		    glDisable(GL_ALPHA_TEST);
		glThis->alpha_test = dwRenderState;
	        break;

	    case D3DRENDERSTATE_TEXTUREMAG: {     /* 17 */
	        DWORD tex_mag = 0xFFFFFFFF;

	        switch ((D3DTEXTUREFILTER) dwRenderState) {
		    case D3DFILTER_NEAREST:
		        tex_mag = D3DTFG_POINT;
			break;
		    case D3DFILTER_LINEAR:
		        tex_mag = D3DTFG_LINEAR;
			break;
		    default:
			ERR("Unhandled texture mag %ld !\n",dwRenderState);
	        }

		if (tex_mag != 0xFFFFFFFF) {
		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MAGFILTER, tex_mag);
		}
	    } break;

	    case D3DRENDERSTATE_TEXTUREMIN: {       /* 18 */
	        DWORD tex_min = 0xFFFFFFFF;

	        switch ((D3DTEXTUREFILTER) dwRenderState) {
		    case D3DFILTER_NEAREST:
		        tex_min = D3DTFN_POINT;
			break;
		    case D3DFILTER_LINEAR:
		        tex_min = D3DTFN_LINEAR;
			break;
		    default:
			ERR("Unhandled texture min %ld !\n",dwRenderState);
	        }

		if (tex_min != 0xFFFFFFFF) {
		    IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MINFILTER, tex_min);
		}
	    } break;

	    case D3DRENDERSTATE_SRCBLEND:           /* 19 */
	    case D3DRENDERSTATE_DESTBLEND:          /* 20 */
	        glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1]),
			    convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1]));
	        break;

	    case D3DRENDERSTATE_TEXTUREMAPBLEND: {  /* 21 */
		IDirect3DDevice7 *d3ddev = ICOM_INTERFACE(This, IDirect3DDevice7);
		
	        switch ((D3DTEXTUREBLEND) dwRenderState) {
		    case D3DTBLEND_DECAL:
		        if (glThis->current_tex_env != GL_REPLACE) {
			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
			    glThis->current_tex_env = GL_REPLACE;
			}
			break;
		    case D3DTBLEND_DECALALPHA:
			if (glThis->current_tex_env != GL_REPLACE) {
			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
			    glThis->current_tex_env = GL_DECAL;
			}
			break;
		    case D3DTBLEND_MODULATE:
			if (glThis->current_tex_env != GL_MODULATE) {
			    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			    glThis->current_tex_env = GL_MODULATE;
			}
			break;
		    case D3DTBLEND_MODULATEALPHA:
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
			IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
			break;
		    default:
		        ERR("Unhandled texture environment %ld !\n",dwRenderState);
		}
	    } break;

	    case D3DRENDERSTATE_CULLMODE:           /* 22 */
	        switch ((D3DCULL) dwRenderState) {
		    case D3DCULL_NONE:
		         if (glThis->cull_face != 0) {
			     glDisable(GL_CULL_FACE);
			     glThis->cull_face = 0;
			 }
			 break;
		    case D3DCULL_CW:
			 if (glThis->cull_face == 0) {
			     glEnable(GL_CULL_FACE);
			     glThis->cull_face = 1;
			 }
			 glFrontFace(GL_CCW);
			 glCullFace(GL_BACK);
			 break;
		    case D3DCULL_CCW:
			 if (glThis->cull_face == 0) {
			     glEnable(GL_CULL_FACE);
			     glThis->cull_face = 1;
			 }
			 glFrontFace(GL_CW);
			 glCullFace(GL_BACK);
			 break;
		    default:
			 ERR("Unhandled cull mode %ld !\n",dwRenderState);
		}
	        break;

	    case D3DRENDERSTATE_ZFUNC:            /* 23 */
	        glDepthFunc(convert_D3D_compare_to_GL(dwRenderState));
	        break;
	      
	    case D3DRENDERSTATE_ALPHAREF:   /* 24 */
	    case D3DRENDERSTATE_ALPHAFUNC:  /* 25 */
	        glAlphaFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_ALPHAFUNC - 1]),
			    (lpStateBlock->render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) / 255.0);
	        break;

	    case D3DRENDERSTATE_DITHERENABLE:     /* 26 */
	        if (dwRenderState)
		    glEnable(GL_DITHER);
		else
		    glDisable(GL_DITHER);
	        break;

	    case D3DRENDERSTATE_ALPHABLENDENABLE:   /* 27 */
	        if ((dwRenderState != 0) && (glThis->blending == 0)) {
		    glEnable(GL_BLEND);
		} else if ((dwRenderState == 0) && (glThis->blending != 0)) {
		    glDisable(GL_BLEND);
		}
	        glThis->blending = dwRenderState;
	        break;
	      
	    case D3DRENDERSTATE_FOGENABLE: /* 28 */
	        /* Nothing to do here. Only the storage matters :-) */
	        break;

	    case D3DRENDERSTATE_SPECULARENABLE: /* 29 */
	        if (dwRenderState)
		    ERR(" Specular Lighting not supported yet.\n");
	        break;
	      
	    case D3DRENDERSTATE_SUBPIXEL:  /* 31 */
	    case D3DRENDERSTATE_SUBPIXELX: /* 32 */
	        /* We do not support this anyway, so why protest :-) */
	        break; 

 	    case D3DRENDERSTATE_STIPPLEDALPHA: /* 33 */
	        if (dwRenderState)
		    ERR(" Stippled Alpha not supported yet.\n");
		break;

	    case D3DRENDERSTATE_FOGCOLOR: { /* 34 */
	        GLfloat color[4];
		color[0] = ((dwRenderState >> 16) & 0xFF)/255.0f;
		color[1] = ((dwRenderState >>  8) & 0xFF)/255.0f;
		color[2] = ((dwRenderState >>  0) & 0xFF)/255.0f;
		color[3] = ((dwRenderState >> 24) & 0xFF)/255.0f;
		glFogfv(GL_FOG_COLOR,color);
		/* Note: glFogiv does not seem to work */
	    } break;

 	    case D3DRENDERSTATE_FOGTABLEMODE:  /* 35 */
 	    case D3DRENDERSTATE_FOGVERTEXMODE: /* 140 */
 	    case D3DRENDERSTATE_FOGSTART:      /* 36 */
	    case D3DRENDERSTATE_FOGEND:        /* 37 */
	        /* Nothing to do here. Only the storage matters :-) */
		break;

	    case D3DRENDERSTATE_FOGDENSITY:    /* 38 */
		glFogi(GL_FOG_DENSITY,*(float*)&dwRenderState);
		break;

	    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
	        /* This needs to be fixed. */
	        if ((dwRenderState != 0) && (glThis->blending == 0)) {
		    glEnable(GL_BLEND);
		} else if ((dwRenderState == 0) && (glThis->blending != 0)) {
		    glDisable(GL_BLEND);
		}
	        glThis->blending = dwRenderState;
	        break;

	    case D3DRENDERSTATE_ZBIAS: /* 47 */
	        /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */
	        if (dwRenderState == 0) {
		    glDisable(GL_POLYGON_OFFSET_FILL);
		    glDisable(GL_POLYGON_OFFSET_LINE);
		    glDisable(GL_POLYGON_OFFSET_POINT);
		} else {
		    glEnable(GL_POLYGON_OFFSET_FILL);
		    glEnable(GL_POLYGON_OFFSET_LINE);
		    glEnable(GL_POLYGON_OFFSET_POINT);
		    glPolygonOffset(1.0, dwRenderState * 1.0);
		}
	        break;
	      
	    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
	        break;

	    case D3DRENDERSTATE_STENCILENABLE:    /* 52 */
	        if ((dwRenderState != 0) && (glThis->stencil_test == 0))
		    glEnable(GL_STENCIL_TEST);
		else if ((dwRenderState == 0) && (glThis->stencil_test != 0))
		    glDisable(GL_STENCIL_TEST);
	        glThis->stencil_test = dwRenderState;
		break;
	    
	    case D3DRENDERSTATE_STENCILFAIL:      /* 53 */
	    case D3DRENDERSTATE_STENCILZFAIL:     /* 54 */
	    case D3DRENDERSTATE_STENCILPASS:      /* 55 */
		glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFAIL - 1]),
			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILZFAIL - 1]),
			    convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILPASS - 1]));
		break;

	    case D3DRENDERSTATE_STENCILFUNC:      /* 56 */
	    case D3DRENDERSTATE_STENCILREF:       /* 57 */
	    case D3DRENDERSTATE_STENCILMASK:      /* 58 */
		glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFUNC - 1]),
			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILREF - 1],
			      lpStateBlock->render_state[D3DRENDERSTATE_STENCILMASK - 1]);
		break;
	  
	    case D3DRENDERSTATE_STENCILWRITEMASK: /* 59 */
	        glStencilMask(dwRenderState);
	        break;

	    case D3DRENDERSTATE_TEXTUREFACTOR:      /* 60 */
	        /* Only the storage matters... */
	        break;

	    case D3DRENDERSTATE_CLIPPING:          /* 136 */
	    case D3DRENDERSTATE_CLIPPLANEENABLE: { /* 152 */
		    GLint i;
		    DWORD mask, runner;
		    
		    if (dwRenderStateType == D3DRENDERSTATE_CLIPPING) {
			mask = ((dwRenderState) ?
				(This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) : (0x00000000));
		    } else {
			mask = dwRenderState;
		    }
		    for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner = (runner << 1)) {
			if (mask & runner) {
			    GLint enabled;
			    glGetIntegerv(GL_CLIP_PLANE0 + i, &enabled);
			    if (enabled == GL_FALSE) {
			        glEnable(GL_CLIP_PLANE0 + i);
				/* Need to force a transform change so that this clipping plane parameters are sent
				 * properly to GL.
				 */
				glThis->transform_state = GL_TRANSFORM_NONE;
			    }
			} else {
			    glDisable(GL_CLIP_PLANE0 + i);
			}
		    }
		}
	        break;

	    case D3DRENDERSTATE_LIGHTING:    /* 137 */
	        /* Nothing to do, only storage matters... */
	        break;
		
	    case D3DRENDERSTATE_AMBIENT: {            /* 139 */
	        float light[4];

		light[0] = ((dwRenderState >> 16) & 0xFF) / 255.0;
		light[1] = ((dwRenderState >>  8) & 0xFF) / 255.0;
		light[2] = ((dwRenderState >>  0) & 0xFF) / 255.0;
		light[3] = ((dwRenderState >> 24) & 0xFF) / 255.0;
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light);
	    } break;

	    case D3DRENDERSTATE_COLORVERTEX:          /* 141 */
	          /* Nothing to do here.. Only storage matters */
	          break;
		  
	    case D3DRENDERSTATE_LOCALVIEWER:          /* 142 */
	        if (dwRenderState)
		    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
		else
		    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
		break;

	    case D3DRENDERSTATE_NORMALIZENORMALS:     /* 143 */
	        if (dwRenderState) {
		    glEnable(GL_NORMALIZE);
		    glEnable(GL_RESCALE_NORMAL);
		} else {
		    glDisable(GL_NORMALIZE);
		    glDisable(GL_RESCALE_NORMAL);
		}
		break;

	    case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE:    /* 145 */
	    case D3DRENDERSTATE_SPECULARMATERIALSOURCE:   /* 146 */
	    case D3DRENDERSTATE_AMBIENTMATERIALSOURCE:    /* 147 */
	    case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE:   /* 148 */
	        /* Nothing to do here. Only the storage matters :-) */
		break;

	    default:
	        ERR("Unhandled dwRenderStateType %s (%08x) value : %08lx !\n",
		    _get_renderstate(dwRenderStateType), dwRenderStateType, dwRenderState);
	}
	LEAVE_GL();
    }
}

void store_render_state(IDirect3DDeviceImpl *This,
			D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK *lpStateBlock)
{
    TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState);
    
    /* Some special cases first.. */
    if (dwRenderStateType == D3DRENDERSTATE_SRCBLEND) {
        if (dwRenderState == D3DBLEND_BOTHSRCALPHA) {
	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_SRCALPHA;
	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_SRCALPHA;
	    return;
	} else if (dwRenderState == D3DBLEND_BOTHINVSRCALPHA) {
	    lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_INVSRCALPHA;
	    lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_INVSRCALPHA;
	    return;
	}
    } else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) {
        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSU - 1] = dwRenderState;
        lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSV - 1] = dwRenderState;
    } else if (dwRenderStateType == D3DRENDERSTATE_WRAPU) {
        if (dwRenderState) 
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_U;
	else
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_U;
    } else if (dwRenderStateType == D3DRENDERSTATE_WRAPV) {
        if (dwRenderState) 
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_V;
	else
	    lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_V;
    }
    
    /* Default case */
    lpStateBlock->render_state[dwRenderStateType - 1] = dwRenderState;
}

void get_render_state(IDirect3DDeviceImpl *This,
		      D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK *lpStateBlock)
{
    *lpdwRenderState = lpStateBlock->render_state[dwRenderStateType - 1];
    if (TRACE_ON(ddraw))
        TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), *lpdwRenderState);
}

void apply_render_state(IDirect3DDeviceImpl *This, STATEBLOCK *lpStateBlock)
{
    DWORD i;
    TRACE("(%p,%p)\n", This, lpStateBlock);
    for(i = 0; i < HIGHEST_RENDER_STATE; i++)
	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;
static DWORD current_tex_width;
static DWORD current_tex_height;
static BOOLEAN need_alignement_restore;
static int current_storage_width;

HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLuint level, GLenum *current_internal_format,
					  BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck, DWORD tex_width, DWORD tex_height)
{
    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 :-) */
    BYTE bpp = GET_BPP(surf_ptr->surface_desc);
    BOOL sub_texture = TRUE;

    need_alignement_restore = FALSE;
    
    current_surface = surf_ptr;
    current_level = level;

    /* First, do some sanity checks ... */
    if ((surf_ptr->surface_desc.u1.lPitch % bpp) != 0) {
	FIXME("Warning : pitch is not a multiple of BPP - not supported yet !\n");
    }

    /* Note: we only check width here as you cannot have width non-zero while height is set to zero */
    if (tex_width == 0) {
	sub_texture = FALSE;
	
	tex_width = surf_ptr->surface_desc.dwWidth;
	tex_height = surf_ptr->surface_desc.dwHeight;
    }

    current_tex_width = tex_width;
    current_tex_height = tex_height;

    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->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x00)) {
		error = TRUE;
	    } else {
		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->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x0000)) {
		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 {
		    error = TRUE;
		}
	    } else {
		if ((src_pf->u2.dwRBitMask == 0xF800) &&
		    (src_pf->u3.dwGBitMask == 0x07E0) &&
		    (src_pf->u4.dwBBitMask == 0x001F)) {
		    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 == 0x7C00) &&
			   (src_pf->u3.dwGBitMask == 0x03E0) &&
			   (src_pf->u4.dwBBitMask == 0x001F)) {
		    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->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x000000)) {
		error = TRUE;
	    } else {
		if ((src_pf->u2.dwRBitMask == 0xFF0000) &&
		    (src_pf->u3.dwGBitMask == 0x00FF00) &&
		    (src_pf->u4.dwBBitMask == 0x0000FF)) {
		    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->dwFlags & DDPF_ALPHAPIXELS) &&
		(src_pf->u5.dwRGBAlphaBitMask != 0x00000000)) {
		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 {
		    error = TRUE;
		}
	    } else {
		if ((src_pf->u2.dwRBitMask == 0x00FF0000) &&
		    (src_pf->u3.dwGBitMask == 0x0000FF00) &&
		    (src_pf->u4.dwBBitMask == 0x000000FF)) {
		    if (need_alpha_ck == TRUE) {
			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) {
	ERR("Unsupported pixel format for textures : \n");
	if (ERR_ON(ddraw)) {
	    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,
			 tex_width, tex_height, 0,
			 current_format, current_pixel_format, NULL);
	    *current_internal_format = internal_format;
	}
    }

    if ((sub_texture == TRUE) && (convert_type == NO_CONVERSION)) {
	current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp;
    } else {
	if (surf_ptr->surface_desc.u1.lPitch == (surf_ptr->surface_desc.dwWidth * bpp)) {
	    current_storage_width = 0;
	} else {
	    current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp;
	}	
    }
    glPixelStorei(GL_UNPACK_ROW_LENGTH, current_storage_width);

    return DD_OK;
}

HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, void **temp_buffer)
{
    const DDSURFACEDESC * const src_d = (DDSURFACEDESC *)&(current_surface->surface_desc);
    void *surf_buffer = NULL;
    RECT lrect;
    DWORD width, height;
    BYTE bpp = GET_BPP(current_surface->surface_desc);
    int line_increase;
    
    if (rect == NULL) {
	lrect.top = 0;
	lrect.left = 0;
	lrect.bottom = current_tex_height;
	lrect.right = current_tex_width;
	rect = &lrect;
    }

    width = rect->right - rect->left;
    height = rect->bottom - rect->top;

    /* Used when converting stuff */
    line_increase = src_d->dwWidth - width;
    
    switch (convert_type) {
        case CONVERT_PALETTED: {
	    IDirectDrawPaletteImpl* pal = current_surface->palette;
	    BYTE table[256][4];
	    int i;
	    int x, y;
	    BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *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, 
					 current_tex_width * current_tex_height * sizeof(DWORD));
	    dst = (BYTE *) *temp_buffer;

	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    BYTE color = *src++;
		    *dst++ = table[color][0];
		    *dst++ = table[color][1];
		    *dst++ = table[color][2];
		    *dst++ = table[color][3];
		}
		src += line_increase;
	    }
	} 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 ?
	    */
	    int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= 0x0001;
		    dst++;
		}
		src += line_increase;
	    }
	} break;
	
        case CONVERT_CK_5551: {
	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
	    int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = color & 0xFFFE;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= color & 0x0001;
		    dst++;
		}
		src += line_increase;
	    }
	} break;
	
        case CONVERT_CK_4444: {
	    /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
	    int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = color & 0xFFF0;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= color & 0x000F;
		    dst++;
		}
		src += line_increase;
	    }
	} break;
	
        case CONVERT_CK_4444_ARGB: {
	    /* Move the four Alpha bits... */
	    int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = (color & 0x0FFF) << 4;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= (color & 0xF000) >> 12;
		    dst++;
		}
		src += line_increase;
	    }
	} break;
	
        case CONVERT_CK_1555: {
	    int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    WORD color = *src++;
		    *dst = (color & 0x7FFF) << 1;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= (color & 0x8000) >> 15;
		    dst++;
		}
		src += line_increase;
	    }
	} break;
	
        case CONVERT_555: {
	    /* Converting the 0555 format in 5551 packed */
	    int x, y;
	    WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(WORD));
	    dst = (WORD *) *temp_buffer;
	    
	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			WORD color = *src++;
			*dst = (color & 0x7FFF) << 1;
			if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			    *dst |= 0x0001;
			dst++;
		    }
		    src += line_increase;
		}
	    } else {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			WORD color = *src++;
			*dst++ = ((color & 0x7FFF) << 1) | 0x0001;
		    }
		    src += line_increase;
		}
	    }
	    
	} break;
	
        case CONVERT_CK_RGB24: {
	    /* This is a pain :-) */
	    int x, y;
	    BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
	    DWORD *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));
	    dst = (DWORD *) *temp_buffer;

	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    DWORD color = *((DWORD *) src) & 0x00FFFFFF;
		    src += 3;
		    *dst = *src++ << 8;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= 0xFF;
		    dst++;
		}
		src += 3 * line_increase;
	    }
	} break;

        case CONVERT_CK_8888: {
	    /* Just use the alpha component to handle color-keying... */
	    int x, y;
	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));	    
	    dst = (DWORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    DWORD color = *src++;
		    *dst = color & 0xFFFFFF00;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= color & 0x000000FF;
		    dst++;
		}
		src += line_increase;
	    }
	} break;
	
        case CONVERT_CK_8888_ARGB: {
	    int x, y;
	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));	    
	    dst = (DWORD *) *temp_buffer;
	    
	    for (y = 0; y < height; y++) {
		for (x = 0; x < width; x++) {
		    DWORD color = *src++;
		    *dst = (color & 0x00FFFFFF) << 8;
		    if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			(color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			*dst |= (color & 0xFF000000) >> 24;
		    dst++;
		}
		src += line_increase;
	    }
	} break;
	
        case CONVERT_RGB32_888: {
	    /* Just add an alpha component and handle color-keying... */
	    int x, y;
	    DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst;
	    
	    if (*temp_buffer == NULL)
		*temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
					 current_tex_width * current_tex_height * sizeof(DWORD));	    
	    dst = (DWORD *) *temp_buffer;
	    
	    if (src_d->dwFlags & DDSD_CKSRCBLT) {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			DWORD color = *src++;
			*dst = color << 8;
			if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
			    (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
			    *dst |= 0xFF;
			dst++;
		    }
		    src += line_increase;
		}
	    } else {
		for (y = 0; y < height; y++) {
		    for (x = 0; x < width; x++) {
			*dst++ = (*src++ << 8) | 0xFF;
		    }
		    src += line_increase;
		}
	    }
	} break;

        case NO_CONVERSION:
	    /* Nothing to do here as the name suggests... Just set-up the buffer correctly */
	    surf_buffer = (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top));
	    break;
    }

    if (convert_type != NO_CONVERSION) {
	int storage_width;
	
	surf_buffer = *temp_buffer;
	if (width != current_tex_width) {
	    /* Overide the default PixelStore parameter if only using part of the actual texture */
	    storage_width = width;
	    /* This is needed when locking with a rectangle with 'odd' width */
	    if (need_alignement_restore == FALSE) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		need_alignement_restore = TRUE;
	    }
	} else {
	    if (current_surface->surface_desc.u1.lPitch == (current_surface->surface_desc.dwWidth * bpp)) {
		storage_width = 0;
	    } else {
		storage_width = current_surface->surface_desc.u1.lPitch / bpp;
	    }
	    if (need_alignement_restore == TRUE) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 0);
		need_alignement_restore = FALSE;
	    }
	}
	if (storage_width != current_storage_width) {
	    glPixelStorei(GL_UNPACK_ROW_LENGTH, storage_width);
	    current_storage_width = storage_width;
	}
    }
    
    glTexSubImage2D(GL_TEXTURE_2D,
		    current_level,
		    xoffset, yoffset,
		    width, height,
		    current_format,
		    current_pixel_format,
		    surf_buffer);

    return DD_OK;
}

HRESULT upload_surface_to_tex_memory_release(void)
{
    current_surface = NULL;

    if (need_alignement_restore == TRUE) {
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    }
    
    return DD_OK;
}
