- separate geometry tracing in a new debug channel (ddraw_geom)
[wine] / dlls / ddraw / d3dtexture.c
1 /* Direct3D Texture
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains the implementation of interface Direct3DTexture2.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winerror.h"
29 #include "objbase.h"
30 #include "ddraw.h"
31 #include "d3d.h"
32 #include "wine/debug.h"
33
34 #include "mesa_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
37
38 /* Define this if you want to save to a file all the textures used by a game
39    (can be funny to see how they managed to cram all the pictures in
40    texture memory) */
41 #undef TEXTURE_SNOOP
42
43 #ifdef TEXTURE_SNOOP
44 #include <stdio.h>
45
46 static void 
47 snoop_texture(IDirectDrawSurfaceImpl *This) {
48     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
49     char buf[128];
50     FILE *f;
51     
52     sprintf(buf, "tex_%05d_%02d.pnm", glThis->tex_name, This->mipmap_level);
53     f = fopen(buf, "wb");
54     DDRAW_dump_surface_to_disk(This, f);
55 }
56
57 #else
58
59 #define snoop_texture(a)
60
61 #endif
62
63 static IDirectDrawSurfaceImpl *
64 get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr)
65 {
66     /* Now go down the mipmap chain to the next surface */
67     static const DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 };
68     LPDIRECTDRAWSURFACE7 next_level;
69     IDirectDrawSurfaceImpl *surf_ptr;
70     HRESULT hr;
71     
72     hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(tex_ptr, IDirectDrawSurface7),
73                                                 (DDSCAPS2 *) &mipmap_caps, &next_level);
74     if (FAILED(hr)) return NULL;
75     
76     surf_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, next_level);
77     IDirectDrawSurface7_Release(next_level);
78     
79     return surf_ptr;
80 }
81
82 /*******************************************************************************
83  *                         IDirectSurface callback methods
84  */
85 HRESULT
86 gltex_upload_texture(IDirectDrawSurfaceImpl *This) {
87     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
88 #if 0
89     static BOOL color_table_queried = FALSE;
90 #endif
91     static void (*ptr_ColorTableEXT) (GLenum target, GLenum internalformat,
92                                       GLsizei width, GLenum format, GLenum type, const GLvoid *table) = NULL;
93     IDirectDrawSurfaceImpl *surf_ptr;
94     GLuint tex_name = glThis->tex_name;
95     
96     TRACE(" activating OpenGL texture id %d.\n", tex_name);
97     glBindTexture(GL_TEXTURE_2D, tex_name);
98
99     if (This->mipmap_level != 0) {
100         WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", This->mipmap_level);
101     }
102     
103     surf_ptr = This;
104     while (surf_ptr != NULL) {
105         GLenum format = GL_RGBA, pixel_format = GL_UNSIGNED_BYTE; /* This is only to prevent warnings.. */
106         VOID *surface = NULL;
107         DDSURFACEDESC *src_d = (DDSURFACEDESC *)&(surf_ptr->surface_desc);
108         IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private;
109         BOOL upload_done = FALSE;
110         BOOL error = FALSE;
111         
112         if (gl_surf_ptr->dirty_flag == FALSE) {
113             TRACE("   - level %d already uploaded.\n", surf_ptr->mipmap_level);
114         } else {
115             TRACE("   - uploading texture level %d (initial done = %d).\n",
116                   surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done);
117
118             /* Texture snooping for the curious :-) */
119             snoop_texture(surf_ptr);
120     
121             if (src_d->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
122                 /* ****************
123                    Paletted Texture
124                    **************** */
125                 IDirectDrawPaletteImpl* pal = surf_ptr->palette;
126                 BYTE table[256][4];
127                 int i;
128                 
129 #if 0
130                 if (color_table_queried == FALSE) {
131                     ptr_ColorTableEXT =
132                       ((Mesa_DeviceCapabilities *) ((x11_dd_private *) surf_ptr->surface->s.ddraw->d->private)->device_capabilities)->ptr_ColorTableEXT;
133                 }
134 #endif
135                 
136                 if (pal == NULL) {
137                     /* Upload a black texture. The real one will be uploaded on palette change */
138                     WARN("Palettized texture Loading with a NULL palette !\n");
139                     memset(table, 0, 256 * 4);
140                 } else {
141                     /* Get the surface's palette */
142                     for (i = 0; i < 256; i++) {
143                         table[i][0] = pal->palents[i].peRed;
144                         table[i][1] = pal->palents[i].peGreen;
145                         table[i][2] = pal->palents[i].peBlue;
146                         if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
147                             (i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
148                             (i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
149                             /* We should maybe here put a more 'neutral' color than the standard bright purple
150                                one often used by application to prevent the nice purple borders when bi-linear
151                                filtering is on */
152                             table[i][3] = 0x00;
153                         else
154                             table[i][3] = 0xFF;
155                     }
156                 }
157
158                 if (ptr_ColorTableEXT != NULL) {
159                     /* use Paletted Texture Extension */
160                     ptr_ColorTableEXT(GL_TEXTURE_2D,    /* target */
161                                       GL_RGBA,          /* internal format */
162                                       256,              /* table size */
163                                       GL_RGBA,          /* table format */
164                                       GL_UNSIGNED_BYTE, /* table type */
165                                       table);           /* the color table */
166                     
167                     glTexImage2D(GL_TEXTURE_2D,       /* target */
168                                  surf_ptr->mipmap_level, /* level */
169                                  GL_COLOR_INDEX8_EXT, /* internal format */
170                                  src_d->dwWidth, src_d->dwHeight, /* width, height */
171                                  0,                   /* border */
172                                  GL_COLOR_INDEX,      /* texture format */
173                                  GL_UNSIGNED_BYTE,    /* texture type */
174                                  src_d->lpSurface); /* the texture */
175                     
176                     upload_done = TRUE;
177                 } else {
178                     DWORD i;
179                     BYTE *src = (BYTE *) src_d->lpSurface, *dst;
180                     
181                     surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
182                     dst = (BYTE *) surface;
183                     
184                     for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
185                         BYTE color = *src++;
186                         *dst++ = table[color][0];
187                         *dst++ = table[color][1];
188                         *dst++ = table[color][2];
189                         *dst++ = table[color][3];
190                     }
191                     
192                     format = GL_RGBA;
193                     pixel_format = GL_UNSIGNED_BYTE;
194                 }
195             } else if (src_d->ddpfPixelFormat.dwFlags & DDPF_RGB) {
196                 /* ************
197                    RGB Textures
198                    ************ */
199                 if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) {
200                     if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xE0) &&
201                         (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x1C) &&
202                         (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x03)) {
203                         /* **********************
204                            GL_UNSIGNED_BYTE_3_3_2
205                            ********************** */
206                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
207                             /* This texture format will never be used.. So do not care about color keying
208                                up until the point in time it will be needed :-) */
209                             error = TRUE;
210                         } else {
211                             format = GL_RGB;
212                             pixel_format = GL_UNSIGNED_BYTE_3_3_2;
213                         }
214                     } else {
215                         error = TRUE;
216                     }
217                 } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) {
218                     if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF800) &&
219                         (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x07E0) &&
220                         (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
221                         (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
222                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
223                             /* Converting the 565 format in 5551 packed to emulate color-keying.
224                                
225                                Note : in all these conversion, it would be best to average the averaging
226                                       pixels to get the color of the pixel that will be color-keyed to
227                                       prevent 'color bleeding'. This will be done later on if ever it is
228                                       too visible.
229                                       
230                                Note2: when using color-keying + alpha, are the alpha bits part of the
231                                       color-space or not ?
232                             */
233                             DWORD i;
234                             WORD *src = (WORD *) src_d->lpSurface, *dst;
235                             
236                             surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
237                                                          src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
238                             dst = (WORD *) surface;
239                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
240                                 WORD color = *src++;
241                                 *dst = ((color & 0xFFC0) | ((color & 0x1F) << 1));
242                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
243                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
244                                     *dst |= 0x0001;
245                                 dst++;
246                             }
247                             
248                             format = GL_RGBA;
249                             pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
250                         } else {
251                             format = GL_RGB;
252                             pixel_format = GL_UNSIGNED_SHORT_5_6_5;
253                         }
254                     } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF800) &&
255                                (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x07C0) &&
256                                (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x003E) &&
257                                (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) {
258                         format = GL_RGBA;
259                         pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;               
260                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
261                             /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
262                             DWORD i;
263                             WORD *src = (WORD *) src_d->lpSurface, *dst;
264                             
265                             surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
266                                                          src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
267                             dst = (WORD *) surface;
268                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
269                                 WORD color = *src++;
270                                 *dst = color & 0xFFFE;
271                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
272                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
273                                     *dst |= color & 0x0001;
274                                 dst++;
275                             }
276                         }
277                     } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xF000) &&
278                                (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0F00) &&
279                                (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x00F0) &&
280                                (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) {
281                         format = GL_RGBA;
282                         pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;             
283                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
284                             /* Change the alpha value of the color-keyed pixels to emulate color-keying. */
285                             DWORD i;
286                             WORD *src = (WORD *) src_d->lpSurface, *dst;
287                     
288                             surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
289                                                          src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
290                             dst = (WORD *) surface;
291                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
292                                 WORD color = *src++;
293                                 *dst = color & 0xFFF0;
294                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
295                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
296                                     *dst |= color & 0x000F;
297                                 dst++;
298                             }
299                         }
300                     } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x0F00) &&
301                                (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x00F0) &&
302                                (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000F) &&
303                                (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) {
304                         /* Move the four Alpha bits... */
305                         DWORD i;
306                         WORD *src = (WORD *) src_d->lpSurface, *dst;
307                         
308                         surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
309                                                      src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
310                         dst = surface;
311                         
312                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
313                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
314                                 WORD color = *src++;
315                                 *dst = (color & 0x0FFF) << 4;
316                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
317                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
318                                     *dst |= (color & 0xF000) >> 12;
319                                 dst++;
320                             }
321                         } else {
322                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
323                                 WORD color = *src++;
324                                 *dst++ = (((color & 0x0FFF) << 4) |
325                                           ((color & 0xF000) >> 12));
326                             }
327                         }
328
329                         format = GL_RGBA;
330                         pixel_format = GL_UNSIGNED_SHORT_4_4_4_4;               
331                     } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x7C00) &&
332                                (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x03E0) &&
333                                (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
334                                (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) {
335                         /* Converting the 1555 format in 5551 packed */
336                         DWORD i;
337                         WORD *src = (WORD *) src_d->lpSurface, *dst;
338                         
339                         surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
340                                                      src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
341                         dst = (WORD *) surface;
342                         
343                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
344                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
345                                 WORD color = *src++;
346                                 *dst = (color & 0x7FFF) << 1;
347                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
348                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
349                                     *dst |= (color & 0x8000) >> 15;
350                                 dst++;
351                             }
352                         } else {
353                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
354                                 WORD color = *src++;
355                                 *dst++ = (((color & 0x7FFF) << 1) |
356                                           ((color & 0x8000) >> 15));
357                             }             
358                         }
359                         
360                         format = GL_RGBA;
361                         pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
362                     } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x7C00) &&
363                                (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x03E0) &&
364                                (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
365                                (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
366                         /* Converting the 0555 format in 5551 packed */
367                         DWORD i;
368                         WORD *src = (WORD *) src_d->lpSurface, *dst;
369                         
370                         surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
371                                                      src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
372                         dst = (WORD *) surface;
373                         
374                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
375                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
376                                 WORD color = *src++;
377                                 *dst = (color & 0x7FFF) << 1;
378                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
379                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
380                                     *dst |= 0x0001;
381                                 dst++;
382                             }
383                         } else {
384                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
385                                 WORD color = *src++;
386                                 *dst++ = ((color & 0x7FFF) << 1) | 0x0001;
387                             }
388                         }
389                         
390                         format = GL_RGBA;
391                         pixel_format = GL_UNSIGNED_SHORT_5_5_5_1;
392                     } else {
393                         error = TRUE;
394                     }
395                 } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) {
396                     if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
397                         (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
398                         (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
399                         (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
400                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
401                             /* This is a pain :-) */
402                             DWORD i;
403                             BYTE *src = (BYTE *) src_d->lpSurface;
404                             DWORD *dst;
405                             
406                             surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
407                                                           src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
408                             dst = (DWORD *) surface;
409                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
410                                 DWORD color = *((DWORD *) src) & 0x00FFFFFF;
411                                 src += 3;
412                                 *dst = *src++ << 8;
413                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
414                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
415                                     *dst |= 0xFF;
416                                 dst++;
417                             }
418                             format = GL_RGBA;
419                             pixel_format = GL_UNSIGNED_INT_8_8_8_8;
420                         } else {
421                             format = GL_BGR;
422                             pixel_format = GL_UNSIGNED_BYTE;
423                         }
424                     } else {
425                         error = TRUE;
426                     }
427                 } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) {
428                     if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0xFF000000) &&
429                         (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x00FF0000) &&
430                         (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x0000FF00) &&
431                         (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000000FF)) {
432                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
433                             /* Just use the alpha component to handle color-keying... */
434                             DWORD i;
435                             DWORD *src = (DWORD *) src_d->lpSurface, *dst;
436                             
437                             surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
438                                                           src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
439                             dst = (DWORD *) surface;
440                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
441                                 DWORD color = *src++;
442                                 *dst = color & 0xFFFFFF00;
443                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
444                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
445                                     *dst |= color & 0x000000FF;
446                                 dst++;
447                             }
448                         }
449                         format = GL_RGBA;
450                         pixel_format = GL_UNSIGNED_INT_8_8_8_8;
451                     } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
452                                (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
453                                (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
454                                (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xFF000000)) {
455                         /* Convert from ARGB (Windows' format) to RGBA.
456                            Note: need to check for GL extensions handling ARGB instead of always converting */
457                         DWORD i;
458                         DWORD *src = (DWORD *) src_d->lpSurface, *dst;
459                         
460                         surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
461                         dst = (DWORD *) surface;
462                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
463                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
464                                 DWORD color = *src++;
465                                 *dst = (color & 0x00FFFFFF) << 8;
466                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
467                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
468                                     *dst |= (color & 0xFF000000) >> 24;
469                                 dst++;
470                             }
471                         } else {
472                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
473                                 DWORD color = *src++; 
474                                 *dst  = (color & 0x00FFFFFF) << 8; 
475                                 *dst |= (color & 0xFF000000) >> 24;
476                                 dst++;
477                             }
478                         }
479                         format = GL_RGBA;
480                         pixel_format = GL_UNSIGNED_INT_8_8_8_8;
481                     } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
482                                (src_d->ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
483                                (src_d->ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
484                                (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
485                         /* Just add an alpha component and handle color-keying... */
486                         DWORD i;
487                         DWORD *src = (DWORD *) src_d->lpSurface, *dst;
488                         
489                         surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD));
490                         dst = (DWORD *) surface;
491                         
492                         if (src_d->dwFlags & DDSD_CKSRCBLT) {
493                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
494                                 DWORD color = *src++;
495                                 *dst = color << 8;
496                                 if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) ||
497                                     (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
498                                     *dst |= 0xFF;
499                                 dst++;
500                             }
501                         } else {
502                             for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
503                                 *dst++ = (*src++ << 8) | 0xFF;
504                             }
505                         }
506                         format = GL_RGBA;
507                         pixel_format = GL_UNSIGNED_INT_8_8_8_8;
508                     } else {
509                         error = TRUE;
510                     }
511                 } else {
512                     error = TRUE;
513                 }
514             } else {
515                 error = TRUE;
516             } 
517             
518             if ((upload_done == FALSE) && (error == FALSE)) {
519                 if (gl_surf_ptr->initial_upload_done == FALSE) {
520                     glTexImage2D(GL_TEXTURE_2D,
521                                  surf_ptr->mipmap_level,
522                                  format,
523                                  src_d->dwWidth, src_d->dwHeight,
524                                  0,
525                                  format,
526                                  pixel_format,
527                                  surface == NULL ? src_d->lpSurface : surface);
528                     gl_surf_ptr->initial_upload_done = TRUE;
529                 } else {
530                     glTexSubImage2D(GL_TEXTURE_2D,
531                                     surf_ptr->mipmap_level,
532                                     0, 0,
533                                     src_d->dwWidth, src_d->dwHeight,
534                                     format,
535                                     pixel_format,
536                                     surface == NULL ? src_d->lpSurface : surface);
537                 }
538                 gl_surf_ptr->dirty_flag = FALSE;
539                 
540                 if (surface) HeapFree(GetProcessHeap(), 0, surface);
541             } else if (error == TRUE) {
542                 if (ERR_ON(ddraw)) {
543                     ERR("  unsupported pixel format for textures : \n");
544                     DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat);
545                 }
546             }
547         }
548
549         surf_ptr = get_sub_mimaplevel(surf_ptr);
550       }
551
552     return DD_OK;
553 }
554
555 HRESULT WINAPI
556 Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface,
557                                        LPDIRECT3DDEVICE lpDirect3DDevice,
558                                        LPDIRECTDRAWSURFACE lpDDSurface)
559 {
560     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
561     FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface);
562     return DD_OK;
563 }
564
565 static HRESULT
566 gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDCOLORKEY ckey )
567 {
568     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
569
570     glThis->dirty_flag = TRUE;
571     /* TODO: check color-keying on mipmapped surfaces... */
572     
573     return DD_OK;
574 }
575
576 HRESULT WINAPI
577 Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface,
578                                               DWORD dwStart,
579                                               DWORD dwCount)
580 {
581     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
582     FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount);
583     return DD_OK;
584 }
585
586 HRESULT WINAPI
587 Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface)
588 {
589     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
590     FIXME("(%p/%p)->(): stub!\n", This, iface);
591     return DD_OK;
592 }
593
594 HRESULT WINAPI
595 Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface,
596                                          LPDIRECT3DDEVICE2 lpDirect3DDevice2,
597                                          LPD3DTEXTUREHANDLE lpHandle)
598 {
599     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
600     IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2);
601     
602     TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle);
603
604     /* The handle is simply the pointer to the implementation structure */
605     *lpHandle = (D3DTEXTUREHANDLE) This;
606
607     TRACE(" returning handle %08lx.\n", *lpHandle);
608     
609     /* Now set the device for this texture */
610     This->d3ddevice = lpDeviceImpl;
611
612     return D3D_OK;
613 }
614
615 HRESULT WINAPI
616 Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
617                                     LPDIRECT3DTEXTURE2 lpD3DTexture2)
618 {
619     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
620     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2);
621     return DD_OK;
622 }
623
624 static void gltex_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal)
625 {
626     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
627     
628     /* First call the previous set_palette function */
629     glThis->set_palette(This, pal);
630     
631     /* And set the dirty flag */
632     glThis->dirty_flag = TRUE;
633
634     /* TODO: check palette on mipmapped surfaces... */
635 }
636
637 static void
638 gltex_final_release(IDirectDrawSurfaceImpl *This)
639 {
640     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
641     DWORD mem_used;
642     int i;
643
644     TRACE(" deleting texture with GL id %d.\n", glThis->tex_name);
645
646     /* And delete texture handle */
647     ENTER_GL();
648     if (glThis->tex_name != 0)
649         glDeleteTextures(1, &(glThis->tex_name));
650     LEAVE_GL(); 
651
652     /* And if this texture was the current one, remove it at the device level */
653     if (This->d3ddevice != NULL)
654         for (i = 0; i < MAX_TEXTURES; i++)
655             if (This->d3ddevice->current_texture[i] == This)
656                 This->d3ddevice->current_texture[i] = NULL;
657
658     /* All this should be part of main surface management not just a hack for texture.. */
659     if (glThis->loaded) {
660         mem_used = This->surface_desc.dwHeight *
661                    This->surface_desc.u1.lPitch;
662         This->ddraw_owner->free_memory(This->ddraw_owner, mem_used);
663     }
664
665     glThis->final_release(This);
666 }
667
668 static void
669 gltex_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
670 {
671     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
672     
673     glThis->lock_update(This, pRect, dwFlags);
674 }
675
676 static void
677 gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
678 {
679     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
680
681     glThis->unlock_update(This, pRect);
682     
683     /* Set the dirty flag according to the lock type */
684     if ((This->lastlocktype & DDLOCK_READONLY) == 0)
685         glThis->dirty_flag = TRUE;
686 }
687
688 HRESULT WINAPI
689 GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface,
690                                   LPDIRECT3DTEXTURE2 lpD3DTexture2)
691 {
692     ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
693     IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2);
694     IDirectDrawSurfaceImpl *dst_ptr = This;
695     HRESULT ret_value = D3D_OK;
696    
697     TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2);
698
699     if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) ||
700         (src_ptr->surface_desc.u2.dwMipMapCount != dst_ptr->surface_desc.u2.dwMipMapCount)) {
701         ERR("Trying to load surfaces with different mip-map counts !\n");
702     }
703
704     /* Now loop through all mipmap levels and load all of them... */
705     while (1) {
706         IDirect3DTextureGLImpl *gl_dst_ptr = (IDirect3DTextureGLImpl *) dst_ptr->tex_private;
707         DDSURFACEDESC *src_d, *dst_d;
708         
709         if (gl_dst_ptr != NULL) {
710             if (gl_dst_ptr->loaded == FALSE) {
711                 /* Only check memory for not already loaded texture... */
712                 DWORD mem_used = dst_ptr->surface_desc.dwHeight * dst_ptr->surface_desc.u1.lPitch;
713                 if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) {
714                     TRACE(" out of virtual memory... Warning application.\n");
715                     return D3DERR_TEXTURE_LOAD_FAILED;
716                 }
717             }
718             gl_dst_ptr->loaded = TRUE;
719         }
720     
721         TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, dst_ptr, src_ptr->mipmap_level);
722
723         if ( dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD )
724             /* If the surface is not allocated and its location is not yet specified,
725                force it to video memory */ 
726             if ( !(dst_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) )
727                 dst_ptr->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
728
729         /* Suppress the ALLOCONLOAD flag */
730         dst_ptr->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
731     
732         /* After seeing some logs, not sure at all about this... */
733         if (dst_ptr->palette == NULL) {
734             dst_ptr->palette = src_ptr->palette;
735             if (src_ptr->palette != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette));
736         } else {
737             if (src_ptr->palette != NULL) {
738                 PALETTEENTRY palent[256];
739                 IDirectDrawPalette_GetEntries(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette),
740                                               0, 0, 256, palent);
741                 IDirectDrawPalette_SetEntries(ICOM_INTERFACE(dst_ptr->palette, IDirectDrawPalette),
742                                               0, 0, 256, palent);
743             }
744         }
745         
746         /* Copy one surface on the other */
747         dst_d = (DDSURFACEDESC *)&(dst_ptr->surface_desc);
748         src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc);
749
750         if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) {
751             /* Should also check for same pixel format, u1.lPitch, ... */
752             ERR("Error in surface sizes\n");
753             return D3DERR_TEXTURE_LOAD_FAILED;
754         } else {
755             /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
756             /* I should put a macro for the calculus of bpp */
757           
758             /* Copy also the ColorKeying stuff */
759             if (src_d->dwFlags & DDSD_CKSRCBLT) {
760                 dst_d->dwFlags |= DDSD_CKSRCBLT;
761                 dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
762                 dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
763             }
764
765             /* Copy the main memory texture into the surface that corresponds to the OpenGL
766                texture object. */
767             memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
768
769             if (gl_dst_ptr != NULL) {
770                 /* If the GetHandle was not done, it is an error... */
771                 if (gl_dst_ptr->tex_name == 0) ERR("Unbound GL texture !!!\n");
772
773                 /* Set this texture as dirty */
774                 gl_dst_ptr->dirty_flag = TRUE;
775             }
776         }
777
778         src_ptr = get_sub_mimaplevel(src_ptr);
779         dst_ptr = get_sub_mimaplevel(dst_ptr);
780
781         if ((src_ptr == NULL) || (dst_ptr == NULL)) {
782             if (src_ptr != dst_ptr) {
783                 ERR(" Loading surface with different mipmap structure !!!\n");
784             }
785             break;
786         }
787     }
788
789     return ret_value;
790 }
791
792 HRESULT WINAPI
793 Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface,
794                                             REFIID riid,
795                                             LPVOID* obp)
796 {
797     TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
798     return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface),
799                                               riid,
800                                               obp);
801 }
802
803 ULONG WINAPI
804 Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface)
805 {
806     TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
807     return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
808 }
809
810 ULONG WINAPI
811 Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface)
812 {
813     TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
814     return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface));
815 }
816
817 HRESULT WINAPI
818 Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface,
819                                             REFIID riid,
820                                             LPVOID* obp)
821 {
822     TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp);
823     return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface),
824                                               riid,
825                                               obp);
826 }
827
828 ULONG WINAPI
829 Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface)
830 {
831     TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
832     return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
833 }
834
835 ULONG WINAPI
836 Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface)
837 {
838     TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface);
839     return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
840 }
841
842 HRESULT WINAPI
843 Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface,
844                                             DWORD dwStart,
845                                             DWORD dwCount)
846 {
847     TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount);
848     return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
849                                             dwStart,
850                                             dwCount);
851 }
852
853 HRESULT WINAPI
854 Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface,
855                                        LPDIRECT3DDEVICE lpDirect3DDevice,
856                                        LPD3DTEXTUREHANDLE lpHandle)
857 {
858     TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle);
859     return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
860                                        COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice),
861                                        lpHandle);
862 }
863
864 HRESULT WINAPI
865 Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface,
866                                   LPDIRECT3DTEXTURE lpD3DTexture)
867 {
868     TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture);
869     return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
870                                   COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture));
871 }
872
873 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
874 # define XCAST(fun)     (typeof(VTABLE_IDirect3DTexture2.fun))
875 #else
876 # define XCAST(fun)     (void*)
877 #endif
878
879 ICOM_VTABLE(IDirect3DTexture2) VTABLE_IDirect3DTexture2 =
880 {
881     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
882     XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface,
883     XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef,
884     XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release,
885     XCAST(GetHandle) Main_IDirect3DTextureImpl_2_1T_GetHandle,
886     XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
887     XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
888 };
889
890 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
891 #undef XCAST
892 #endif
893
894
895 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
896 # define XCAST(fun)     (typeof(VTABLE_IDirect3DTexture.fun))
897 #else
898 # define XCAST(fun)     (void*)
899 #endif
900
901 ICOM_VTABLE(IDirect3DTexture) VTABLE_IDirect3DTexture =
902 {
903     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
904     XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_1_QueryInterface,
905     XCAST(AddRef) Thunk_IDirect3DTextureImpl_1_AddRef,
906     XCAST(Release) Thunk_IDirect3DTextureImpl_1_Release,
907     XCAST(Initialize) Main_IDirect3DTextureImpl_1_Initialize,
908     XCAST(GetHandle) Thunk_IDirect3DTextureImpl_1_GetHandle,
909     XCAST(PaletteChanged) Thunk_IDirect3DTextureImpl_1_PaletteChanged,
910     XCAST(Load) Thunk_IDirect3DTextureImpl_1_Load,
911     XCAST(Unload) Main_IDirect3DTextureImpl_1_Unload,
912 };
913
914 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
915 #undef XCAST
916 #endif
917
918 HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, 
919                           IDirectDrawSurfaceImpl *main)
920 {
921     /* First, initialize the texture vtables... */
922     ICOM_INIT_INTERFACE(surf, IDirect3DTexture,  VTABLE_IDirect3DTexture);
923     ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2);
924         
925     /* Only create all the private stuff if we actually have an OpenGL context.. */
926     if (d3d->current_device != NULL) {
927         IDirect3DTextureGLImpl *private;
928
929         private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
930         if (private == NULL) return DDERR_OUTOFMEMORY;
931
932         private->final_release = surf->final_release;
933         private->lock_update = surf->lock_update;
934         private->unlock_update = surf->unlock_update;
935         private->set_palette = surf->set_palette;
936         
937         /* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
938            Otherwise, it will be uploaded here (and may be invalid). */
939         surf->final_release = gltex_final_release;
940         surf->lock_update = gltex_lock_update;
941         surf->unlock_update = gltex_unlock_update;
942         surf->tex_private = private;
943         surf->aux_setcolorkey_cb = gltex_setcolorkey_cb;
944         surf->set_palette = gltex_set_palette;
945
946         ENTER_GL();
947         if (surf->mipmap_level == 0) {
948             glGenTextures(1, &(private->tex_name));
949             if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n");
950             TRACE(" GL texture created for surface %p (private data at %p and GL id %d).\n", surf, private, private->tex_name);
951         } else {
952             private->tex_name = ((IDirect3DTextureGLImpl *) (main->tex_private))->tex_name;
953             TRACE(" GL texture created for surface %p (private data at %p and GL id reusing id %d from surface %p (%p)).\n",
954                   surf, private, private->tex_name, main, main->tex_private);
955         }
956         LEAVE_GL();
957
958         /* And set the dirty flag accordingly */
959         private->dirty_flag = (at_creation == FALSE);
960         private->initial_upload_done = FALSE;
961     }
962
963     return D3D_OK;
964 }