From 094f6bc9858a723efcca714000dd31b691d50477 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Wed, 4 Jun 2003 23:22:13 +0000 Subject: [PATCH] Refactoring of the texture upload code. --- dlls/ddraw/d3dtexture.c | 550 +++---------------------------------- dlls/ddraw/mesa.c | 556 ++++++++++++++++++++++++++++++++++++++ dlls/ddraw/mesa_private.h | 9 + 3 files changed, 608 insertions(+), 507 deletions(-) diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c index 75ef6eac2e8..77957bf8adf 100644 --- a/dlls/ddraw/d3dtexture.c +++ b/dlls/ddraw/d3dtexture.c @@ -84,500 +84,7 @@ get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr) */ 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 @@ gltex_flush_texture_GL_to_memory(IDirectDrawSurfaceImpl *surf_ptr) { } 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 @@ gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDCOLORKEY c 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 @@ gltex_bltfast(IDirectDrawSurfaceImpl *surf_ptr, DWORD dstx, !((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 @@ static void gltex_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteIm 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(); } diff --git a/dlls/ddraw/mesa.c b/dlls/ddraw/mesa.c index 937a64721ad..e78434dcfc3 100644 --- a/dlls/ddraw/mesa.c +++ b/dlls/ddraw/mesa.c @@ -20,6 +20,8 @@ #include "config.h" +#define NONAMELESSUNION +#define NONAMELESSSTRUCT #include "windef.h" #include "objbase.h" #include "ddraw.h" @@ -531,3 +533,557 @@ void apply_render_state(IDirect3DDeviceImpl *This, STATEBLOCK *lpStateBlock) 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; +} diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h index 5bbab4098b2..da8de08e422 100644 --- a/dlls/ddraw/mesa_private.h +++ b/dlls/ddraw/mesa_private.h @@ -70,6 +70,9 @@ typedef struct IDirect3DTextureGLImpl /* 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 store_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwR 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 {