Drop GLcontext typedef and use struct gl_context instead
[mesa.git] / src / mesa / drivers / windows / gldirect / dx7 / gld_texture_dx7.c
1 /****************************************************************************
2 *
3 * Mesa 3-D graphics library
4 * Direct3D Driver Interface
5 *
6 * ========================================================================
7 *
8 * Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 *
28 * ======================================================================
29 *
30 * Language: ANSI C
31 * Environment: Windows 9x/2000/XP/XBox (Win32)
32 *
33 * Description: Texture / Bitmap functions
34 *
35 ****************************************************************************/
36
37 #include "dglcontext.h"
38 #include "ddlog.h"
39 #include "gld_dx7.h"
40
41 //#include <d3dx8tex.h>
42
43 #include "texformat.h"
44 #include "colormac.h"
45 #include "texstore.h"
46 #include "image.h"
47 // #include "mem.h"
48
49 //---------------------------------------------------------------------------
50
51 #define GLD_FLIP_HEIGHT(y,h) (gldCtx->dwHeight - (y) - (h))
52
53 D3DX_SURFACEFORMAT _gldD3DXFormatFromSurface(IDirectDrawSurface7 *pSurface);
54
55 //---------------------------------------------------------------------------
56 // 1D texture fetch
57 //---------------------------------------------------------------------------
58
59 #define CHAN_SRC( t, i, j, k, sz ) \
60 ((GLchan *)(t)->Data + (i) * (sz))
61 #define UBYTE_SRC( t, i, j, k, sz ) \
62 ((GLubyte *)(t)->Data + (i) * (sz))
63 #define USHORT_SRC( t, i, j, k ) \
64 ((GLushort *)(t)->Data + (i))
65 #define FLOAT_SRC( t, i, j, k ) \
66 ((GLfloat *)(t)->Data + (i))
67
68 //---------------------------------------------------------------------------
69
70 static void gld_fetch_1d_texel_X8R8G8B8(
71 const struct gl_texture_image *texImage,
72 GLint i, GLint j, GLint k, GLchan *texel )
73 {
74 const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
75 GLchan *rgba = (GLchan *)texel;
76 rgba[RCOMP] = src[2];
77 rgba[GCOMP] = src[1];
78 rgba[BCOMP] = src[0];
79 rgba[ACOMP] = CHAN_MAX;
80 }
81
82 //---------------------------------------------------------------------------
83
84 static void gld_fetch_1d_texel_f_X8R8G8B8(
85 const struct gl_texture_image *texImage,
86 GLint i, GLint j, GLint k, GLfloat *texel )
87 {
88 const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
89 texel[RCOMP] = CHAN_TO_FLOAT(src[0]);
90 texel[GCOMP] = CHAN_TO_FLOAT(src[1]);
91 texel[BCOMP] = CHAN_TO_FLOAT(src[2]);
92 texel[ACOMP] = 1.f;
93 }
94
95 //---------------------------------------------------------------------------
96
97 static void gld_fetch_1d_texel_X1R5G5B5(
98 const struct gl_texture_image *texImage,
99 GLint i, GLint j, GLint k, GLchan *texel )
100 {
101 const GLushort *src = USHORT_SRC( texImage, i, j, k );
102 GLchan *rgba = (GLchan *) texel; GLushort s = *src;
103 rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 );
104 rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 );
105 rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 );
106 rgba[ACOMP] = CHAN_MAX;
107 }
108
109 //---------------------------------------------------------------------------
110
111 static void gld_fetch_1d_texel_f_X1R5G5B5(
112 const struct gl_texture_image *texImage,
113 GLint i, GLint j, GLint k, GLfloat *texel )
114 {
115 const GLushort *src = USHORT_SRC( texImage, i, j, k );
116 GLushort s = *src;
117 texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 );
118 texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 );
119 texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 );
120 texel[ACOMP] = 1.f;
121 }
122
123 //---------------------------------------------------------------------------
124
125 static void gld_fetch_1d_texel_X4R4G4B4(
126 const struct gl_texture_image *texImage,
127 GLint i, GLint j, GLint k, GLchan *texel )
128 {
129 const GLushort *src = USHORT_SRC( texImage, i, j, k );
130 GLchan *rgba = (GLchan *) texel; GLushort s = *src;
131 rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf );
132 rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf );
133 rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf );
134 rgba[ACOMP] = CHAN_MAX;
135 }
136
137 //---------------------------------------------------------------------------
138
139 static void gld_fetch_1d_texel_f_X4R4G4B4(
140 const struct gl_texture_image *texImage,
141 GLint i, GLint j, GLint k, GLfloat *texel )
142 {
143 const GLushort *src = USHORT_SRC( texImage, i, j, k );
144 GLushort s = *src;
145 texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf );
146 texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf );
147 texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf );
148 texel[ACOMP] = 1.f;
149 }
150
151 //---------------------------------------------------------------------------
152
153 #undef CHAN_SRC
154 #undef UBYTE_SRC
155 #undef USHORT_SRC
156 #undef FLOAT_SRC
157
158 //---------------------------------------------------------------------------
159 // 2D texture fetch
160 //---------------------------------------------------------------------------
161
162 #define CHAN_SRC( t, i, j, k, sz ) \
163 ((GLchan *)(t)->Data + ((t)->Width * (j) + (i)) * (sz))
164 #define UBYTE_SRC( t, i, j, k, sz ) \
165 ((GLubyte *)(t)->Data + ((t)->Width * (j) + (i)) * (sz))
166 #define USHORT_SRC( t, i, j, k ) \
167 ((GLushort *)(t)->Data + ((t)->Width * (j) + (i)))
168 #define FLOAT_SRC( t, i, j, k ) \
169 ((GLfloat *)(t)->Data + ((t)->Width * (j) + (i)))
170
171 //---------------------------------------------------------------------------
172
173 static void gld_fetch_2d_texel_X8R8G8B8(
174 const struct gl_texture_image *texImage,
175 GLint i, GLint j, GLint k, GLchan *texel )
176 {
177 const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
178 GLchan *rgba = (GLchan *)texel;
179 rgba[RCOMP] = src[2];
180 rgba[GCOMP] = src[1];
181 rgba[BCOMP] = src[0];
182 rgba[ACOMP] = CHAN_MAX;
183 }
184
185 //---------------------------------------------------------------------------
186
187 static void gld_fetch_2d_texel_f_X8R8G8B8(
188 const struct gl_texture_image *texImage,
189 GLint i, GLint j, GLint k, GLfloat *texel )
190 {
191 const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
192 texel[RCOMP] = CHAN_TO_FLOAT(src[0]);
193 texel[GCOMP] = CHAN_TO_FLOAT(src[1]);
194 texel[BCOMP] = CHAN_TO_FLOAT(src[2]);
195 texel[ACOMP] = 1.f;
196 }
197
198 //---------------------------------------------------------------------------
199
200 static void gld_fetch_2d_texel_X1R5G5B5(
201 const struct gl_texture_image *texImage,
202 GLint i, GLint j, GLint k, GLchan *texel )
203 {
204 const GLushort *src = USHORT_SRC( texImage, i, j, k );
205 GLchan *rgba = (GLchan *) texel; GLushort s = *src;
206 rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 );
207 rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 );
208 rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 );
209 rgba[ACOMP] = CHAN_MAX;
210 }
211
212 //---------------------------------------------------------------------------
213
214 static void gld_fetch_2d_texel_f_X1R5G5B5(
215 const struct gl_texture_image *texImage,
216 GLint i, GLint j, GLint k, GLfloat *texel )
217 {
218 const GLushort *src = USHORT_SRC( texImage, i, j, k );
219 GLushort s = *src;
220 texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 );
221 texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 );
222 texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 );
223 texel[ACOMP] = 1.f;
224 }
225
226 //---------------------------------------------------------------------------
227
228 static void gld_fetch_2d_texel_X4R4G4B4(
229 const struct gl_texture_image *texImage,
230 GLint i, GLint j, GLint k, GLchan *texel )
231 {
232 const GLushort *src = USHORT_SRC( texImage, i, j, k );
233 GLchan *rgba = (GLchan *) texel; GLushort s = *src;
234 rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf );
235 rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf );
236 rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf );
237 rgba[ACOMP] = CHAN_MAX;
238 }
239
240 //---------------------------------------------------------------------------
241
242 static void gld_fetch_2d_texel_f_X4R4G4B4(
243 const struct gl_texture_image *texImage,
244 GLint i, GLint j, GLint k, GLfloat *texel )
245 {
246 const GLushort *src = USHORT_SRC( texImage, i, j, k );
247 GLushort s = *src;
248 texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf );
249 texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf );
250 texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf );
251 texel[ACOMP] = 1.f;
252 }
253
254 //---------------------------------------------------------------------------
255
256 #undef CHAN_SRC
257 #undef UBYTE_SRC
258 #undef USHORT_SRC
259 #undef FLOAT_SRC
260
261 //---------------------------------------------------------------------------
262 // 3D texture fetch
263 //---------------------------------------------------------------------------
264
265 #define CHAN_SRC( t, i, j, k, sz ) \
266 (GLchan *)(t)->Data + (((t)->Height * (k) + (j)) * \
267 (t)->Width + (i)) * (sz)
268 #define UBYTE_SRC( t, i, j, k, sz ) \
269 ((GLubyte *)(t)->Data + (((t)->Height * (k) + (j)) * \
270 (t)->Width + (i)) * (sz))
271 #define USHORT_SRC( t, i, j, k ) \
272 ((GLushort *)(t)->Data + (((t)->Height * (k) + (j)) * \
273 (t)->Width + (i)))
274 #define FLOAT_SRC( t, i, j, k ) \
275 ((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) * \
276 (t)->Width + (i)))
277
278 //---------------------------------------------------------------------------
279
280 static void gld_fetch_3d_texel_X8R8G8B8(
281 const struct gl_texture_image *texImage,
282 GLint i, GLint j, GLint k, GLchan *texel )
283 {
284 const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
285 GLchan *rgba = (GLchan *)texel;
286 rgba[RCOMP] = src[2];
287 rgba[GCOMP] = src[1];
288 rgba[BCOMP] = src[0];
289 rgba[ACOMP] = CHAN_MAX;
290 }
291
292 //---------------------------------------------------------------------------
293
294 static void gld_fetch_3d_texel_f_X8R8G8B8(
295 const struct gl_texture_image *texImage,
296 GLint i, GLint j, GLint k, GLfloat *texel )
297 {
298 const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
299 texel[RCOMP] = CHAN_TO_FLOAT(src[0]);
300 texel[GCOMP] = CHAN_TO_FLOAT(src[1]);
301 texel[BCOMP] = CHAN_TO_FLOAT(src[2]);
302 texel[ACOMP] = 1.f;
303 }
304
305 //---------------------------------------------------------------------------
306
307 static void gld_fetch_3d_texel_X1R5G5B5(
308 const struct gl_texture_image *texImage,
309 GLint i, GLint j, GLint k, GLchan *texel )
310 {
311 const GLushort *src = USHORT_SRC( texImage, i, j, k );
312 GLchan *rgba = (GLchan *) texel; GLushort s = *src;
313 rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 );
314 rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 );
315 rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 );
316 rgba[ACOMP] = CHAN_MAX;
317 }
318
319 //---------------------------------------------------------------------------
320
321 static void gld_fetch_3d_texel_f_X1R5G5B5(
322 const struct gl_texture_image *texImage,
323 GLint i, GLint j, GLint k, GLfloat *texel )
324 {
325 const GLushort *src = USHORT_SRC( texImage, i, j, k );
326 GLushort s = *src;
327 texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 10) & 0xf8) * 255 / 0xf8 );
328 texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 5) & 0xf8) * 255 / 0xf8 );
329 texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf8) * 255 / 0xf8 );
330 texel[ACOMP] = 1.f;
331 }
332
333 //---------------------------------------------------------------------------
334
335 static void gld_fetch_3d_texel_X4R4G4B4(
336 const struct gl_texture_image *texImage,
337 GLint i, GLint j, GLint k, GLchan *texel )
338 {
339 const GLushort *src = USHORT_SRC( texImage, i, j, k );
340 GLchan *rgba = (GLchan *) texel; GLushort s = *src;
341 rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf );
342 rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf );
343 rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf );
344 rgba[ACOMP] = CHAN_MAX;
345 }
346
347 //---------------------------------------------------------------------------
348
349 static void gld_fetch_3d_texel_f_X4R4G4B4(
350 const struct gl_texture_image *texImage,
351 GLint i, GLint j, GLint k, GLfloat *texel )
352 {
353 const GLushort *src = USHORT_SRC( texImage, i, j, k );
354 GLushort s = *src;
355 texel[RCOMP] = UBYTE_TO_FLOAT( ((s >> 8) & 0xf) * 255 / 0xf );
356 texel[GCOMP] = UBYTE_TO_FLOAT( ((s >> 4) & 0xf) * 255 / 0xf );
357 texel[BCOMP] = UBYTE_TO_FLOAT( ((s ) & 0xf) * 255 / 0xf );
358 texel[ACOMP] = 1.f;
359 }
360
361 //---------------------------------------------------------------------------
362
363 #undef CHAN_SRC
364 #undef UBYTE_SRC
365 #undef USHORT_SRC
366 #undef FLOAT_SRC
367
368 //---------------------------------------------------------------------------
369 // Direct3D texture formats that have no Mesa equivalent
370 //---------------------------------------------------------------------------
371
372 const struct gl_texture_format _gld_texformat_X8R8G8B8 = {
373 MESA_FORMAT_ARGB8888, /* MesaFormat */
374 GL_RGBA, /* BaseFormat */
375 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
376 8, /* RedBits */
377 8, /* GreenBits */
378 8, /* BlueBits */
379 0, /* AlphaBits */
380 0, /* LuminanceBits */
381 0, /* IntensityBits */
382 0, /* IndexBits */
383 0, /* DepthBits */
384 4, /* TexelBytes */
385 _mesa_texstore_argb8888, /* StoreTexImageFunc */
386 gld_fetch_1d_texel_X8R8G8B8, /* FetchTexel1D */
387 gld_fetch_2d_texel_X8R8G8B8, /* FetchTexel2D */
388 gld_fetch_3d_texel_X8R8G8B8, /* FetchTexel3D */
389 gld_fetch_1d_texel_f_X8R8G8B8, /* FetchTexel1Df */
390 gld_fetch_2d_texel_f_X8R8G8B8, /* FetchTexel2Df */
391 gld_fetch_3d_texel_f_X8R8G8B8, /* FetchTexel3Df */
392 };
393
394 const struct gl_texture_format _gld_texformat_X1R5G5B5 = {
395 MESA_FORMAT_ARGB1555, /* MesaFormat */
396 GL_RGBA, /* BaseFormat */
397 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
398 5, /* RedBits */
399 5, /* GreenBits */
400 5, /* BlueBits */
401 0, /* AlphaBits */
402 0, /* LuminanceBits */
403 0, /* IntensityBits */
404 0, /* IndexBits */
405 0, /* DepthBits */
406 2, /* TexelBytes */
407 _mesa_texstore_argb1555, /* StoreTexImageFunc */
408 gld_fetch_1d_texel_X1R5G5B5, /* FetchTexel1D */
409 gld_fetch_2d_texel_X1R5G5B5, /* FetchTexel2D */
410 gld_fetch_3d_texel_X1R5G5B5, /* FetchTexel3D */
411 gld_fetch_1d_texel_f_X1R5G5B5, /* FetchTexel1Df */
412 gld_fetch_2d_texel_f_X1R5G5B5, /* FetchTexel2Df */
413 gld_fetch_3d_texel_f_X1R5G5B5, /* FetchTexel3Df */
414 };
415
416 const struct gl_texture_format _gld_texformat_X4R4G4B4 = {
417 MESA_FORMAT_ARGB4444, /* MesaFormat */
418 GL_RGBA, /* BaseFormat */
419 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
420 4, /* RedBits */
421 4, /* GreenBits */
422 4, /* BlueBits */
423 0, /* AlphaBits */
424 0, /* LuminanceBits */
425 0, /* IntensityBits */
426 0, /* IndexBits */
427 0, /* DepthBits */
428 2, /* TexelBytes */
429 _mesa_texstore_argb4444, /* StoreTexImageFunc */
430 gld_fetch_1d_texel_X4R4G4B4, /* FetchTexel1D */
431 gld_fetch_2d_texel_X4R4G4B4, /* FetchTexel2D */
432 gld_fetch_3d_texel_X4R4G4B4, /* FetchTexel3D */
433 gld_fetch_1d_texel_f_X4R4G4B4, /* FetchTexel1Df */
434 gld_fetch_2d_texel_f_X4R4G4B4, /* FetchTexel2Df */
435 gld_fetch_3d_texel_f_X4R4G4B4, /* FetchTexel3Df */
436 };
437
438 //---------------------------------------------------------------------------
439 // Texture unit constants
440 //---------------------------------------------------------------------------
441
442 // List of possible combinations of texture environments.
443 // Example: GLD_TEXENV_MODULATE_RGBA means
444 // GL_MODULATE, GL_RGBA base internal format.
445 #define GLD_TEXENV_DECAL_RGB 0
446 #define GLD_TEXENV_DECAL_RGBA 1
447 #define GLD_TEXENV_DECAL_ALPHA 2
448 #define GLD_TEXENV_REPLACE_RGB 3
449 #define GLD_TEXENV_REPLACE_RGBA 4
450 #define GLD_TEXENV_REPLACE_ALPHA 5
451 #define GLD_TEXENV_MODULATE_RGB 6
452 #define GLD_TEXENV_MODULATE_RGBA 7
453 #define GLD_TEXENV_MODULATE_ALPHA 8
454 #define GLD_TEXENV_BLEND_RGB 9
455 #define GLD_TEXENV_BLEND_RGBA 10
456 #define GLD_TEXENV_BLEND_ALPHA 11
457 #define GLD_TEXENV_ADD_RGB 12
458 #define GLD_TEXENV_ADD_RGBA 13
459 #define GLD_TEXENV_ADD_ALPHA 14
460
461 // Per-stage (i.e. per-unit) texture environment
462 typedef struct {
463 DWORD ColorArg1; // Colour argument 1
464 D3DTEXTUREOP ColorOp; // Colour operation
465 DWORD ColorArg2; // Colour argument 2
466 DWORD AlphaArg1; // Alpha argument 1
467 D3DTEXTUREOP AlphaOp; // Alpha operation
468 DWORD AlphaArg2; // Alpha argument 2
469 } GLD_texenv;
470
471 // TODO: Do we really need to set ARG1 and ARG2 every time?
472 // They seem to always be TEXTURE and CURRENT respectively.
473
474 // C = Colour out
475 // A = Alpha out
476 // Ct = Colour from Texture
477 // Cf = Colour from fragment (diffuse)
478 // At = Alpha from Texture
479 // Af = Alpha from fragment (diffuse)
480 // Cc = GL_TEXTURE_ENV_COLOUR (GL_BLEND)
481 const GLD_texenv gldTexEnv[] = {
482 // DECAL_RGB: C=Ct, A=Af
483 {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT,
484 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
485 // DECAL_RGBA: C=Cf(1-At)+CtAt, A=Af
486 {D3DTA_TEXTURE, D3DTOP_BLENDTEXTUREALPHA, D3DTA_CURRENT,
487 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
488 // DECAL_ALPHA: <undefined> use DECAL_RGB
489 {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT,
490 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
491
492 // REPLACE_RGB: C=Ct, A=Af
493 {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT,
494 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
495 // REPLACE_RGBA: C=Ct, A=At
496 {D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT,
497 D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT},
498 // REPLACE_ALPHA: C=Cf, A=At
499 {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT,
500 D3DTA_TEXTURE, D3DTOP_SELECTARG1, D3DTA_CURRENT},
501
502 // MODULATE_RGB: C=CfCt, A=Af
503 {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT,
504 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
505 // MODULATE_RGBA: C=CfCt, A=AfAt
506 {D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT,
507 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT},
508 // MODULATE_ALPHA: C=Cf, A=AfAt
509 {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT,
510 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT},
511
512 //
513 // DX7 Does not support D3DTOP_LERP
514 // Emulate(?) via D3DTOP_ADDSMOOTH
515 //
516 #if 0
517 // BLEND_RGB: C=Cf(1-Ct)+CcCt, A=Af
518 {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT,
519 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
520 // BLEND_RGBA: C=Cf(1-Ct)+CcCt, A=AfAt
521 {D3DTA_TEXTURE, D3DTOP_LERP, D3DTA_CURRENT,
522 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT},
523 #else
524 // BLEND_RGB: C=Cf(1-Ct)+CcCt, A=Af
525 {D3DTA_TEXTURE, D3DTOP_ADDSMOOTH, D3DTA_CURRENT,
526 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
527 // BLEND_RGBA: C=Cf(1-Ct)+CcCt, A=AfAt
528 {D3DTA_TEXTURE, D3DTOP_ADDSMOOTH, D3DTA_CURRENT,
529 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT},
530 #endif
531 // BLEND_ALPHA: C=Cf, A=AfAt
532 {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT,
533 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT},
534
535 // ADD_RGB: C=Cf+Ct, A=Af
536 {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT,
537 D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT},
538 // ADD_RGBA: C=Cf+Ct, A=AfAt
539 {D3DTA_TEXTURE, D3DTOP_ADD, D3DTA_CURRENT,
540 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT},
541 // ADD_ALPHA: C=Cf, A=AfAt
542 {D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_CURRENT,
543 D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT},
544 };
545
546 //---------------------------------------------------------------------------
547
548 D3DTEXTUREADDRESS _gldConvertWrap(
549 GLenum wrap)
550 {
551 // ASSERT(wrap==GL_CLAMP || wrap==GL_REPEAT);
552 return (wrap == GL_CLAMP) ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP;
553 }
554
555 //---------------------------------------------------------------------------
556
557 D3DTEXTUREMAGFILTER _gldConvertMagFilter(
558 GLenum magfilter)
559 {
560 ASSERT(magfilter==GL_LINEAR || magfilter==GL_NEAREST);
561 return (magfilter == GL_LINEAR) ? D3DTFG_LINEAR : D3DTFG_POINT;
562 }
563
564 //---------------------------------------------------------------------------
565
566 void _gldConvertMinFilter(
567 GLenum minfilter,
568 D3DTEXTUREMINFILTER *min_filter,
569 D3DTEXTUREMIPFILTER *mip_filter)
570 {
571 switch (minfilter) {
572 case GL_NEAREST:
573 *min_filter = D3DTFN_POINT;
574 *mip_filter = D3DTFP_NONE;
575 break;
576 case GL_LINEAR:
577 *min_filter = D3DTFN_LINEAR;
578 *mip_filter = D3DTFP_NONE;
579 break;
580 case GL_NEAREST_MIPMAP_NEAREST:
581 *min_filter = D3DTFN_POINT;
582 *mip_filter = D3DTFP_POINT;
583 break;
584 case GL_LINEAR_MIPMAP_NEAREST:
585 *min_filter = D3DTFN_LINEAR;
586 *mip_filter = D3DTFP_POINT;
587 break;
588 case GL_NEAREST_MIPMAP_LINEAR:
589 *min_filter = D3DTFN_POINT;
590 *mip_filter = D3DTFP_LINEAR;
591 break;
592 case GL_LINEAR_MIPMAP_LINEAR:
593 *min_filter = D3DTFN_LINEAR;
594 *mip_filter = D3DTFP_LINEAR;
595 break;
596 default:
597 ASSERT(0);
598 }
599 }
600
601 //---------------------------------------------------------------------------
602
603 D3DX_SURFACEFORMAT _gldGLFormatToD3DFormat(
604 GLenum internalFormat)
605 {
606 switch (internalFormat) {
607 case GL_INTENSITY:
608 case GL_INTENSITY4:
609 case GL_INTENSITY8:
610 case GL_INTENSITY12:
611 case GL_INTENSITY16:
612 // LUNIMANCE != INTENSITY, but D3D doesn't have I8 textures
613 return D3DX_SF_L8;
614 case 1:
615 case GL_LUMINANCE:
616 case GL_LUMINANCE4:
617 case GL_LUMINANCE8:
618 case GL_LUMINANCE12:
619 case GL_LUMINANCE16:
620 return D3DX_SF_L8;
621 case GL_ALPHA:
622 case GL_ALPHA4:
623 case GL_ALPHA8:
624 case GL_ALPHA12:
625 case GL_ALPHA16:
626 return D3DX_SF_A8;
627 case GL_COLOR_INDEX:
628 case GL_COLOR_INDEX1_EXT:
629 case GL_COLOR_INDEX2_EXT:
630 case GL_COLOR_INDEX4_EXT:
631 case GL_COLOR_INDEX8_EXT:
632 case GL_COLOR_INDEX12_EXT:
633 case GL_COLOR_INDEX16_EXT:
634 return D3DX_SF_X8R8G8B8;
635 case 2:
636 case GL_LUMINANCE_ALPHA:
637 case GL_LUMINANCE4_ALPHA4:
638 case GL_LUMINANCE6_ALPHA2:
639 case GL_LUMINANCE8_ALPHA8:
640 case GL_LUMINANCE12_ALPHA4:
641 case GL_LUMINANCE12_ALPHA12:
642 case GL_LUMINANCE16_ALPHA16:
643 return D3DX_SF_A8L8;
644 case GL_R3_G3_B2:
645 // TODO: Mesa does not support RGB332 internally
646 return D3DX_SF_X4R4G4B4; //D3DFMT_R3G3B2;
647 case GL_RGB4:
648 return D3DX_SF_X4R4G4B4;
649 case GL_RGB5:
650 return D3DX_SF_R5G5B5;
651 case 3:
652 case GL_RGB:
653 case GL_RGB8:
654 case GL_RGB10:
655 case GL_RGB12:
656 case GL_RGB16:
657 return D3DX_SF_R8G8B8;
658 case GL_RGBA4:
659 return D3DX_SF_A4R4G4B4;
660 case 4:
661 case GL_RGBA:
662 case GL_RGBA2:
663 case GL_RGBA8:
664 case GL_RGB10_A2:
665 case GL_RGBA12:
666 case GL_RGBA16:
667 return D3DX_SF_A8R8G8B8;
668 case GL_RGB5_A1:
669 return D3DX_SF_A1R5G5B5;
670 }
671
672 ASSERT(0);
673
674 // Return an acceptable default
675 return D3DX_SF_A8R8G8B8;
676 }
677
678 //---------------------------------------------------------------------------
679
680 GLenum _gldDecodeBaseFormat(
681 IDirectDrawSurface7 *pTex)
682 {
683 // Examine Direct3D texture and return base OpenGL internal texture format
684 // NOTE: We can't use any base format info from Mesa because D3D might have
685 // used a different texture format when we used D3DXCreateTexture().
686
687 // Base internal format is one of (Red Book p355):
688 // GL_ALPHA,
689 // GL_LUMINANCE,
690 // GL_LUMINANCE_ALPHA,
691 // GL_INTENSITY,
692 // GL_RGB,
693 // GL_RGBA
694
695 // NOTE: INTENSITY not used (not supported by Direct3D)
696 // LUMINANCE has same texture functions as RGB
697 // LUMINANCE_ALPHA has same texture functions as RGBA
698
699 // TODO: cache format instead of using GetLevelDesc()
700 // D3DSURFACE_DESC desc;
701 // _GLD_DX7_TEX(GetLevelDesc(pTex, 0, &desc));
702
703 D3DX_SURFACEFORMAT sf;
704
705 sf = _gldD3DXFormatFromSurface(pTex);
706
707 switch (sf) {
708 case D3DX_SF_R8G8B8:
709 case D3DX_SF_X8R8G8B8:
710 case D3DX_SF_R5G6B5:
711 case D3DX_SF_R5G5B5:
712 case D3DX_SF_R3G3B2:
713 case D3DX_SF_X4R4G4B4:
714 case D3DX_SF_PALETTE8:
715 case D3DX_SF_L8:
716 return GL_RGB;
717 case D3DX_SF_A8R8G8B8:
718 case D3DX_SF_A1R5G5B5:
719 case D3DX_SF_A4R4G4B4:
720 // case D3DX_SF_A8R3G3B2: // Unsupported by DX7
721 // case D3DX_SF_A8P8: // Unsupported by DX7
722 case D3DX_SF_A8L8:
723 // case D3DX_SF_A4L4: // Unsupported by DX7
724 return GL_RGBA;
725 case D3DX_SF_A8:
726 return GL_ALPHA;
727 // Compressed texture formats. Need to check these...
728 case D3DX_SF_DXT1:
729 return GL_RGBA;
730 // case D3DX_SF_DXT2: // Unsupported by DX7
731 return GL_RGB;
732 case D3DX_SF_DXT3:
733 return GL_RGBA;
734 // case D3DX_SF_DXT4: // Unsupported by DX7
735 return GL_RGB;
736 case D3DX_SF_DXT5:
737 return GL_RGBA;
738 }
739
740 // Fell through. Return arbitary default.
741 ASSERT(0); // BANG!
742 return GL_RGBA;
743 }
744
745 //---------------------------------------------------------------------------
746
747 const struct gl_texture_format* _gldMesaFormatForD3DFormat(
748 D3DX_SURFACEFORMAT d3dfmt)
749 {
750 switch (d3dfmt) {
751 case D3DX_SF_A8R8G8B8:
752 return &_mesa_texformat_argb8888;
753 case D3DX_SF_R8G8B8:
754 return &_mesa_texformat_rgb888;
755 case D3DX_SF_R5G6B5:
756 return &_mesa_texformat_rgb565;
757 case D3DX_SF_A4R4G4B4:
758 return &_mesa_texformat_argb4444;
759 case D3DX_SF_A1R5G5B5:
760 return &_mesa_texformat_argb1555;
761 case D3DX_SF_A8L8:
762 return &_mesa_texformat_al88;
763 case D3DX_SF_R3G3B2:
764 return &_mesa_texformat_rgb332;
765 case D3DX_SF_A8:
766 return &_mesa_texformat_a8;
767 case D3DX_SF_L8:
768 return &_mesa_texformat_l8;
769 case D3DX_SF_X8R8G8B8:
770 return &_gld_texformat_X8R8G8B8;
771 case D3DX_SF_R5G5B5:
772 return &_gld_texformat_X1R5G5B5;
773 case D3DX_SF_X4R4G4B4:
774 return &_gld_texformat_X4R4G4B4;
775 }
776
777 // If we reach here then we've made an error somewhere else
778 // by allowing a format that is not supported.
779 ASSERT(0);
780
781 return NULL; // Shut up compiler warning
782 }
783
784 //---------------------------------------------------------------------------
785
786 D3DX_SURFACEFORMAT _gldD3DXFormatFromSurface(
787 IDirectDrawSurface7 *pSurface)
788 {
789 DDPIXELFORMAT ddpf;
790
791 ddpf.dwSize = sizeof(ddpf);
792
793 // Obtain pixel format of surface
794 _GLD_DX7_TEX(GetPixelFormat(pSurface, &ddpf));
795 // Decode to D3DX surface format
796 return D3DXMakeSurfaceFormat(&ddpf);
797 }
798
799 //---------------------------------------------------------------------------
800
801 void _gldClearSurface(
802 IDirectDrawSurface *pSurface,
803 D3DCOLOR dwColour)
804 {
805 DDBLTFX bltFX; // Used for colour fill
806
807 // Initialise struct
808 bltFX.dwSize = sizeof(bltFX);
809 // Set clear colour
810 bltFX.dwFillColor = dwColour;
811 // Clear surface. HW accelerated if available.
812 IDirectDrawSurface7_Blt(pSurface, NULL, NULL, NULL, DDBLT_COLORFILL, &bltFX);
813 }
814
815 //---------------------------------------------------------------------------
816 // Copy* functions
817 //---------------------------------------------------------------------------
818
819 void gldCopyTexImage1D_DX7(
820 struct gl_context *ctx,
821 GLenum target, GLint level,
822 GLenum internalFormat,
823 GLint x, GLint y,
824 GLsizei width, GLint border )
825 {
826 // TODO
827 }
828
829 //---------------------------------------------------------------------------
830
831 void gldCopyTexImage2D_DX7(
832 struct gl_context *ctx,
833 GLenum target,
834 GLint level,
835 GLenum internalFormat,
836 GLint x,
837 GLint y,
838 GLsizei width,
839 GLsizei height,
840 GLint border)
841 {
842 // TODO
843 }
844
845 //---------------------------------------------------------------------------
846
847 void gldCopyTexSubImage1D_DX7(
848 struct gl_context *ctx,
849 GLenum target, GLint level,
850 GLint xoffset, GLint x, GLint y, GLsizei width )
851 {
852 // TODO
853 }
854
855 //---------------------------------------------------------------------------
856
857 void gldCopyTexSubImage2D_DX7(
858 struct gl_context *ctx,
859 GLenum target,
860 GLint level,
861 GLint xoffset,
862 GLint yoffset,
863 GLint x,
864 GLint y,
865 GLsizei width,
866 GLsizei height)
867 {
868 // TODO
869 }
870
871 //---------------------------------------------------------------------------
872
873 void gldCopyTexSubImage3D_DX7(
874 struct gl_context *ctx,
875 GLenum target,
876 GLint level,
877 GLint xoffset,
878 GLint yoffset,
879 GLint zoffset,
880 GLint x,
881 GLint y,
882 GLsizei width,
883 GLsizei height )
884 {
885 // TODO ?
886 }
887
888 //---------------------------------------------------------------------------
889 // Bitmap/Pixel functions
890 //---------------------------------------------------------------------------
891
892 #define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y))
893
894 #define _GLD_FVF_IMAGE (D3DFVF_XYZRHW | D3DFVF_TEX1)
895
896 typedef struct {
897 FLOAT x, y; // 2D raster coords
898 FLOAT z; // depth value
899 FLOAT rhw; // reciprocal homogenous W (always 1.0f)
900 FLOAT tu, tv; // texture coords
901 } _GLD_IMAGE_VERTEX;
902
903 //---------------------------------------------------------------------------
904
905 HRESULT _gldDrawPixels(
906 struct gl_context *ctx,
907 BOOL bChromakey, // Alpha test for glBitmap() images
908 GLint x, // GL x position
909 GLint y, // GL y position (needs flipping)
910 GLsizei width, // Width of input image
911 GLsizei height, // Height of input image
912 IDirectDrawSurface7 *pImage)
913 {
914 //
915 // Draw input image as texture implementing PixelZoom and clipping.
916 // Any fragment operations currently enabled will be used.
917 //
918
919 // NOTE: This DX7 version does not create a new texture in which
920 // to copy the input image, as the image is already a texture.
921
922 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
923 GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx);
924
925 DDSURFACEDESC2 ddsd;
926 _GLD_IMAGE_VERTEX v[4];
927
928 float ZoomWidth, ZoomHeight;
929 float ScaleWidth, ScaleHeight;
930
931 // Fixup for rasterisation rules
932 const float cfEpsilon = 1.0f / (float)height;
933
934 //
935 // Set up the quad like this (ascii-art ahead!)
936 //
937 // 3--2
938 // | |
939 // 0--1
940 //
941 //
942
943 // Set depth
944 v[0].z = v[1].z = v[2].z = v[3].z = ctx->Current.RasterPos[2];
945 // Set Reciprocal Homogenous W
946 v[0].rhw = v[1].rhw = v[2].rhw = v[3].rhw = 1.0f;
947
948 // Set texcoords
949 // Examine texture size - if different to input width and height
950 // then we'll need to munge the texcoords to fit.
951 ddsd.dwSize = sizeof(DDSURFACEDESC2);
952 IDirectDrawSurface7_GetSurfaceDesc(pImage, &ddsd);
953 ScaleWidth = (float)width / (float)ddsd.dwWidth;
954 ScaleHeight = (float)height / (float)ddsd.dwHeight;
955 v[0].tu = 0.0f; v[0].tv = 0.0f;
956 v[1].tu = ScaleWidth; v[1].tv = 0.0f;
957 v[2].tu = ScaleWidth; v[2].tv = ScaleHeight;
958 v[3].tu = 0.0f; v[3].tv = ScaleHeight;
959
960 // Set raster positions
961 ZoomWidth = (float)width * ctx->Pixel.ZoomX;
962 ZoomHeight = (float)height * ctx->Pixel.ZoomY;
963
964 v[0].x = x; v[0].y = GLD_FLIP_Y(y+cfEpsilon);
965 v[1].x = x+ZoomWidth; v[1].y = GLD_FLIP_Y(y+cfEpsilon);
966 v[2].x = x+ZoomWidth; v[2].y = GLD_FLIP_Y(y+ZoomHeight+cfEpsilon);
967 v[3].x = x; v[3].y = GLD_FLIP_Y(y+ZoomHeight+cfEpsilon);
968
969 // Draw image with full HW acceleration
970 // NOTE: Be nice to use a State Block for all this state...
971 IDirect3DDevice7_SetTexture(gld->pDev, 0, pImage);
972 IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
973 IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_CLIPPING, TRUE);
974 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_MINFILTER, D3DTFN_POINT);
975 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_MIPFILTER, D3DTFP_POINT);
976 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_MAGFILTER, D3DTFG_POINT);
977 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
978 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
979 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
980 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
981 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
982 IDirect3DDevice7_SetTextureStageState(gld->pDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
983 // Ensure texture unit 1 is disabled
984 IDirect3DDevice7_SetTextureStageState(gld->pDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
985 IDirect3DDevice7_SetTextureStageState(gld->pDev, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
986
987 //
988 // Emulate Chromakey with an Alpha Test.
989 // [Alpha Test is more widely supported anyway]
990 //
991 if (bChromakey) {
992 // Switch on alpha testing
993 IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE);
994 // Fragment passes is alpha is greater than reference value
995 IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER);
996 // Set alpha reference value between Bitmap alpha values of
997 // zero (transparent) and one (opaque).
998 IDirect3DDevice7_SetRenderState(gld->pDev, D3DRENDERSTATE_ALPHAREF, 0x7f);
999 }
1000
1001 IDirect3DDevice7_DrawPrimitive(gld->pDev, D3DPT_TRIANGLEFAN, _GLD_FVF_IMAGE, &v, 4, 0);
1002
1003 // Reset state to before we messed it up
1004 FLUSH_VERTICES(ctx, _NEW_ALL);
1005
1006 return S_OK;
1007 }
1008
1009 //---------------------------------------------------------------------------
1010
1011 void gld_DrawPixels_DX7(
1012 struct gl_context *ctx,
1013 GLint x, GLint y, GLsizei width, GLsizei height,
1014 GLenum format, GLenum type,
1015 const struct gl_pixelstore_attrib *unpack,
1016 const GLvoid *pixels )
1017 {
1018 GLD_context *gldCtx;
1019 GLD_driver_dx7 *gld;
1020
1021 IDirectDrawSurface7 *pImage;
1022 HRESULT hr;
1023 DDSURFACEDESC2 ddsd;
1024 DWORD dwFlags;
1025 D3DX_SURFACEFORMAT sf;
1026 DWORD dwMipmaps;
1027
1028 const struct gl_texture_format *MesaFormat;
1029
1030 MesaFormat = _mesa_choose_tex_format(ctx, format, format, type);
1031
1032 gldCtx = GLD_GET_CONTEXT(ctx);
1033 gld = GLD_GET_DX7_DRIVER(gldCtx);
1034
1035 dwFlags = D3DX_TEXTURE_NOMIPMAP;
1036 sf = D3DX_SF_A8R8G8B8;
1037 dwMipmaps = 1;
1038
1039 hr = D3DXCreateTexture(
1040 gld->pDev,
1041 &dwFlags,
1042 &width, &height,
1043 &sf, // format
1044 NULL, // palette
1045 &pImage, // Output texture
1046 &dwMipmaps);
1047 if (FAILED(hr)) {
1048 return;
1049 }
1050
1051 // D3DXCreateTexture() may not clear the texture is creates.
1052 _gldClearSurface(pImage, 0);
1053
1054 //
1055 // Use Mesa to fill in image
1056 //
1057
1058 // Lock all of surface
1059 ddsd.dwSize = sizeof(DDSURFACEDESC2);
1060 dwFlags = DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT;
1061 hr = IDirectDrawSurface7_Lock(pImage, NULL, &ddsd, dwFlags, NULL);
1062 if (FAILED(hr)) {
1063 SAFE_RELEASE_SURFACE7(pImage);
1064 return;
1065 }
1066
1067 // unpack image, apply transfer ops and store directly in texture
1068 MesaFormat->StoreImage(
1069 ctx,
1070 2,
1071 GL_RGBA,
1072 &_mesa_texformat_argb8888,
1073 ddsd.lpSurface,
1074 width, height, 1, 0, 0, 0,
1075 ddsd.lPitch,
1076 0, /* dstImageStride */
1077 format, type, pixels, unpack);
1078
1079 IDirectDrawSurface7_Unlock(pImage, NULL);
1080
1081 _gldDrawPixels(ctx, FALSE, x, y, width, height, pImage);
1082
1083 SAFE_RELEASE_SURFACE7(pImage);
1084 }
1085
1086 //---------------------------------------------------------------------------
1087
1088 void gld_ReadPixels_DX7(
1089 struct gl_context *ctx,
1090 GLint x, GLint y, GLsizei width, GLsizei height,
1091 GLenum format, GLenum type,
1092 const struct gl_pixelstore_attrib *pack,
1093 GLvoid *dest)
1094 {
1095 // TODO
1096 #if 0
1097 GLD_context *gldCtx;
1098 GLD_driver_dx7 *gld;
1099
1100 IDirect3DSurface8 *pBackbuffer = NULL;
1101 IDirect3DSurface8 *pNativeImage = NULL;
1102 IDirect3DSurface8 *pCanonicalImage = NULL;
1103
1104 D3DSURFACE_DESC d3dsd;
1105 RECT rcSrc; // Source rect
1106 POINT ptDst; // Dest point
1107 HRESULT hr;
1108 D3DLOCKED_RECT d3dLockedRect;
1109 struct gl_pixelstore_attrib srcPacking;
1110 int i;
1111 GLint DstRowStride;
1112 const struct gl_texture_format *MesaFormat;
1113
1114 switch (format) {
1115 case GL_STENCIL_INDEX:
1116 case GL_DEPTH_COMPONENT:
1117 return;
1118 }
1119
1120 MesaFormat = _mesa_choose_tex_format(ctx, format, format, type);
1121 DstRowStride = _mesa_image_row_stride(pack, width, format, type);
1122
1123 gldCtx = GLD_GET_CONTEXT(ctx);
1124 gld = GLD_GET_DX7_DRIVER(gldCtx);
1125
1126 // Get backbuffer
1127 hr = IDirect3DDevice8_GetBackBuffer(
1128 gld->pDev,
1129 0, // First backbuffer
1130 D3DBACKBUFFER_TYPE_MONO,
1131 &pBackbuffer);
1132 if (FAILED(hr))
1133 return;
1134
1135 // Get backbuffer description
1136 hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd);
1137 if (FAILED(hr)) {
1138 goto gld_ReadPixels_DX7_return;
1139 }
1140
1141 // Create a surface compatible with backbuffer
1142 hr = IDirect3DDevice8_CreateImageSurface(
1143 gld->pDev,
1144 width,
1145 height,
1146 d3dsd.Format,
1147 &pNativeImage);
1148 if (FAILED(hr)) {
1149 goto gld_ReadPixels_DX7_return;
1150 }
1151
1152 // Compute source rect and dest point
1153 SetRect(&rcSrc, 0, 0, width, height);
1154 OffsetRect(&rcSrc, x, GLD_FLIP_HEIGHT(y, height));
1155 ptDst.x = ptDst.y = 0;
1156
1157 // Get source pixels.
1158 //
1159 // This intermediate surface ensure that we can use CopyRects()
1160 // instead of relying on D3DXLoadSurfaceFromSurface(), which may
1161 // try and lock the backbuffer. This way seems safer.
1162 //
1163 hr = IDirect3DDevice8_CopyRects(
1164 gld->pDev,
1165 pBackbuffer,
1166 &rcSrc,
1167 1,
1168 pNativeImage,
1169 &ptDst);
1170 if (FAILED(hr)) {
1171 goto gld_ReadPixels_DX7_return;
1172 }
1173
1174 // Create an RGBA8888 surface
1175 hr = IDirect3DDevice8_CreateImageSurface(
1176 gld->pDev,
1177 width,
1178 height,
1179 D3DFMT_A8R8G8B8,
1180 &pCanonicalImage);
1181 if (FAILED(hr)) {
1182 goto gld_ReadPixels_DX7_return;
1183 }
1184
1185 // Convert to RGBA8888
1186 hr = D3DXLoadSurfaceFromSurface(
1187 pCanonicalImage, // Dest surface
1188 NULL, NULL, // Dest palette, RECT
1189 pNativeImage, // Src surface
1190 NULL, NULL, // Src palette, RECT
1191 D3DX_FILTER_NONE, // Filter
1192 0); // Colourkey
1193 if (FAILED(hr)) {
1194 goto gld_ReadPixels_DX7_return;
1195 }
1196
1197 srcPacking.Alignment = 1;
1198 srcPacking.ImageHeight = height;
1199 srcPacking.LsbFirst = GL_FALSE;
1200 srcPacking.RowLength = 0;
1201 srcPacking.SkipImages = 0;
1202 srcPacking.SkipPixels = 0;
1203 srcPacking.SkipRows = 0;
1204 srcPacking.SwapBytes = GL_FALSE;
1205
1206 // Lock all of image
1207 hr = IDirect3DSurface8_LockRect(pCanonicalImage, &d3dLockedRect, NULL, 0);
1208 if (FAILED(hr)) {
1209 goto gld_ReadPixels_DX7_return;
1210 }
1211
1212 // We need to flip the data. Yuck.
1213 // Perhaps Mesa has a span packer we can use in future...
1214 for (i=0; i<height; i++) {
1215 BYTE *pDestRow = (BYTE*)_mesa_image_address(2,pack, dest, width, height, format, type, 0, i, 0);
1216 BYTE *pSrcRow = (BYTE*)d3dLockedRect.pBits + (d3dLockedRect.Pitch * (height-i-1));
1217 texImage->TexFormat->StoreImage(
1218 ctx,
1219 2,
1220 GL_RGBA, // base format
1221 MesaFormat, // dst format
1222 pDestRow, // dest addr
1223 width, 1, 1, 0, 0, 0, // src x,y,z & dst offsets x,y,z
1224 DstRowStride, // dst row stride
1225 0, // dstImageStride
1226 GL_BGRA, // src format
1227 GL_UNSIGNED_BYTE, // src type
1228 pSrcRow, // src addr
1229 &srcPacking); // packing params of source image
1230 }
1231
1232 IDirect3DSurface8_UnlockRect(pCanonicalImage);
1233
1234 gld_ReadPixels_DX7_return:
1235 SAFE_RELEASE_SURFACE8(pCanonicalImage);
1236 SAFE_RELEASE_SURFACE8(pNativeImage);
1237 SAFE_RELEASE_SURFACE8(pBackbuffer);
1238 #endif
1239 }
1240
1241 //---------------------------------------------------------------------------
1242
1243 void gld_CopyPixels_DX7(
1244 struct gl_context *ctx,
1245 GLint srcx,
1246 GLint srcy,
1247 GLsizei width,
1248 GLsizei height,
1249 GLint dstx,
1250 GLint dsty,
1251 GLenum type)
1252 {
1253 // TODO
1254 #if 0
1255 //
1256 // NOTE: Not allowed to copy vidmem to vidmem!
1257 // Therefore we use an intermediate image surface.
1258 //
1259
1260 GLD_context *gldCtx;
1261 GLD_driver_dx7 *gld;
1262
1263 IDirect3DSurface8 *pBackbuffer;
1264 D3DSURFACE_DESC d3dsd;
1265 IDirect3DSurface8 *pImage;
1266 RECT rcSrc; // Source rect
1267 POINT ptDst; // Dest point
1268 HRESULT hr;
1269
1270 // Only backbuffer
1271 if (type != GL_COLOR)
1272 return;
1273
1274 gldCtx = GLD_GET_CONTEXT(ctx);
1275 gld = GLD_GET_DX7_DRIVER(gldCtx);
1276
1277 // Get backbuffer
1278 hr = IDirect3DDevice8_GetBackBuffer(
1279 gld->pDev,
1280 0, // First backbuffer
1281 D3DBACKBUFFER_TYPE_MONO,
1282 &pBackbuffer);
1283 if (FAILED(hr))
1284 return;
1285
1286 // Get backbuffer description
1287 hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd);
1288 if (FAILED(hr)) {
1289 IDirect3DSurface8_Release(pBackbuffer);
1290 return;
1291 }
1292
1293 // Create a surface compatible with backbuffer
1294 hr = IDirect3DDevice8_CreateImageSurface(
1295 gld->pDev,
1296 width,
1297 height,
1298 d3dsd.Format,
1299 &pImage);
1300 if (FAILED(hr)) {
1301 IDirect3DSurface8_Release(pBackbuffer);
1302 return;
1303 }
1304
1305 // Compute source rect and dest point
1306 SetRect(&rcSrc, 0, 0, width, height);
1307 OffsetRect(&rcSrc, srcx, GLD_FLIP_HEIGHT(srcy, height));
1308 ptDst.x = ptDst.y = 0;
1309
1310 // Get source pixels
1311 hr = IDirect3DDevice8_CopyRects(
1312 gld->pDev,
1313 pBackbuffer,
1314 &rcSrc,
1315 1,
1316 pImage,
1317 &ptDst);
1318 IDirect3DSurface8_Release(pBackbuffer);
1319 if (FAILED(hr)) {
1320 IDirect3DSurface8_Release(pImage);
1321 return;
1322 }
1323
1324 _gldDrawPixels(ctx, FALSE, dstx, dsty, width, height, pImage);
1325
1326 IDirect3DSurface8_Release(pImage);
1327 #endif
1328 }
1329
1330 //---------------------------------------------------------------------------
1331
1332 void gld_Bitmap_DX7(
1333 struct gl_context *ctx,
1334 GLint x,
1335 GLint y,
1336 GLsizei width,
1337 GLsizei height,
1338 const struct gl_pixelstore_attrib *unpack,
1339 const GLubyte *bitmap)
1340 {
1341 GLD_context *gldCtx;
1342 GLD_driver_dx7 *gld;
1343
1344 IDirectDrawSurface7 *pImage; // Bitmap texture
1345 HRESULT hr;
1346 BYTE *pTempBitmap; // Pointer to unpacked bitmap
1347 D3DCOLOR clBitmapOne; // Opaque bitmap colour
1348 D3DCOLOR clBitmapZero; // Transparent bitmap colour
1349 D3DCOLOR *pBits; // Pointer to texture surface
1350 const GLubyte *src;
1351 int i, j, k;
1352
1353 DDSURFACEDESC2 ddsd; // Surface desc returned by lock call
1354 DWORD dwFlags;
1355 D3DX_SURFACEFORMAT sf;
1356 DWORD dwMipmaps;
1357
1358 // Keep a copy of width/height as D3DXCreateTexture() call may alter input dimensions
1359 GLsizei dwWidth = width;
1360 GLsizei dwHeight = height;
1361
1362 gldCtx = GLD_GET_CONTEXT(ctx);
1363 gld = GLD_GET_DX7_DRIVER(gldCtx);
1364
1365 // Bail if no bitmap (only raster pos is updated)
1366 if ((bitmap == NULL) && (width==0) && (height==0))
1367 return;
1368
1369 //
1370 // TODO: Detect conditions when created texture (pImage) is non-pow2.
1371 // Texture coords may need to be adjusted to compensate.
1372 //
1373
1374 clBitmapZero = D3DCOLOR_RGBA(0,0,0,0); // NOTE: Alpha is Zero
1375 clBitmapOne = D3DCOLOR_COLORVALUE(
1376 ctx->Current.RasterColor[0],
1377 ctx->Current.RasterColor[1],
1378 ctx->Current.RasterColor[2],
1379 1.0f); // NOTE: Alpha is One
1380
1381 // Use Mesa to unpack bitmap into a canonical format
1382 pTempBitmap = _mesa_unpack_bitmap(width, height, bitmap, unpack);
1383 if (pTempBitmap == NULL)
1384 return;
1385
1386 // Flags for texture creation
1387 dwFlags = D3DX_TEXTURE_NOMIPMAP;
1388 sf = D3DX_SF_A8R8G8B8;
1389 dwMipmaps = 1;
1390
1391 // Create a D3D texture to hold the bitmap
1392 hr = D3DXCreateTexture(
1393 gld->pDev,
1394 &dwFlags,
1395 &dwWidth, &dwHeight,
1396 &sf, // format
1397 NULL, // palette
1398 &pImage, // Output texture
1399 &dwMipmaps);
1400 if (FAILED(hr)) {
1401 FREE(pTempBitmap);
1402 return;
1403 }
1404
1405 // D3DXCreateTexture may return a texture bigger than we asked for
1406 // (i.e. padded to POW2) so let's clear the entire image bitmap.
1407 // Additional: Looks like this is not strictly necessary.
1408 // _gldClearSurface(pImage, clBitmapZero);
1409
1410 ddsd.dwSize = sizeof(DDSURFACEDESC2);
1411 dwFlags = DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT;
1412 hr = IDirectDrawSurface7_Lock(pImage, NULL, &ddsd, dwFlags, NULL);
1413 if (FAILED(hr)) {
1414 FREE(pTempBitmap);
1415 SAFE_RELEASE_SURFACE7(pImage);
1416 return;
1417 }
1418
1419 #if 0
1420 // DEBUG CODE
1421 if (!(width==ddsd.dwWidth && height==ddsd.dwHeight))
1422 ddlogPrintf(GLDLOG_WARN, "gld_Bitmap: In=%d,%d / Tex=%d,%d", width,height,ddsd.dwWidth,ddsd.dwHeight);
1423 #endif
1424
1425 #if 0
1426 // DEBUG CODE
1427 ddlogPrintf(GLDLOG_SYSTEM, "gld_Bitmap: In=%d,%d / Tex=%d,%d", width,height,ddsd.dwWidth,ddsd.dwHeight);
1428 ddlogPrintf(GLDLOG_SYSTEM, "gld_Bitmap: bpp=%d", ddsd.ddpfPixelFormat.dwRGBBitCount);
1429 #endif
1430
1431 // Cast texel pointer to texture surface.
1432 // We can do this because we used D3DX_SF_A8R8G8B8 as the format
1433 pBits = (D3DCOLOR*)ddsd.lpSurface;
1434
1435
1436 // Copy from the input bitmap into the texture
1437 for (i=0; i<height; i++) {
1438 GLubyte byte;
1439 pBits = (D3DCOLOR*)((BYTE*)ddsd.lpSurface + (i*ddsd.lPitch));
1440 src = (const GLubyte *) _mesa_image_address(2,
1441 &ctx->DefaultPacking, pTempBitmap, width, height, GL_COLOR_INDEX, GL_BITMAP,
1442 0, i, 0);
1443 for (j=0; j<(width>>3); j++) {
1444 byte = *src++;
1445 for (k=0; k<8; k++) {
1446 *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero;
1447 byte <<= 1;
1448 }
1449 }
1450 // Fill remaining bits from bitmap
1451 if (width & 7) {
1452 byte = *src;
1453 for (k=0; k<(width & 7); k++) {
1454 *pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero;
1455 byte <<= 1;
1456 }
1457 }
1458 }
1459
1460 // We're done with the unpacked bitmap
1461 FREE(pTempBitmap);
1462
1463 // Finished with texture surface - unlock it
1464 IDirectDrawSurface7_Unlock(pImage, NULL);
1465
1466 // Use internal function to draw bitmap onto rendertarget
1467 _gldDrawPixels(ctx, TRUE, x, y, width, height, pImage);
1468
1469 // We're done with the bitmap texure - release it
1470 IDirectDrawSurface7_Release(pImage);
1471 }
1472
1473 //---------------------------------------------------------------------------
1474 // Texture functions
1475 //---------------------------------------------------------------------------
1476
1477 void _gldAllocateTexture(
1478 struct gl_context *ctx,
1479 struct gl_texture_object *tObj,
1480 struct gl_texture_image *texImage)
1481 {
1482 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1483 GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx);
1484
1485 HRESULT hr;
1486 IDirectDrawSurface7 *pTex;
1487 D3DX_SURFACEFORMAT d3dFormat;
1488 DWORD dwFlags;
1489 DWORD dwMipmaps;
1490 DWORD dwWidth, dwHeight;
1491
1492 if (!tObj || !texImage)
1493 return;
1494
1495 pTex = (IDirectDrawSurface7*)tObj->DriverData;
1496 if (pTex) {
1497 // Decide whether we can keep existing D3D texture
1498 // by examining top-level surface.
1499 DDSURFACEDESC2 ddsd;
1500 ddsd.dwSize = sizeof(DDSURFACEDESC2);
1501 _GLD_DX7_TEX(GetSurfaceDesc(pTex, &ddsd));
1502 // Release existing texture if not compatible
1503 if ((ddsd.dwWidth == texImage->Width) ||
1504 (ddsd.dwHeight == texImage->Height))
1505 {
1506 return; // Keep the existing texture
1507 }
1508 tObj->DriverData = NULL;
1509 _GLD_DX7_TEX(Release(pTex));
1510 }
1511
1512 dwFlags = (glb.bUseMipmaps) ? 0 : D3DX_TEXTURE_NOMIPMAP;
1513 dwMipmaps = (glb.bUseMipmaps) ? D3DX_DEFAULT : 1;
1514 dwWidth = texImage->Width;
1515 dwHeight = texImage->Height;
1516
1517 d3dFormat = _gldGLFormatToD3DFormat(texImage->IntFormat);
1518 hr = D3DXCreateTexture(
1519 gld->pDev,
1520 &dwFlags,
1521 &dwWidth,
1522 &dwHeight,
1523 &d3dFormat,
1524 NULL,
1525 &pTex,
1526 &dwMipmaps);
1527 if (FAILED(hr)) {
1528 gldLogError(GLDLOG_ERROR, "AllocateTexture failed", hr);
1529 }
1530 tObj->DriverData = pTex;
1531 }
1532
1533 //---------------------------------------------------------------------------
1534
1535 const struct gl_texture_format* gld_ChooseTextureFormat_DX7(
1536 struct gl_context *ctx,
1537 GLint internalFormat,
1538 GLenum srcFormat,
1539 GLenum srcType)
1540 {
1541 // [Based on mesa_choose_tex_format()]
1542 //
1543 // We will choose only texture formats that are supported
1544 // by Direct3D. If the hardware doesn't support a particular
1545 // texture format, then the D3DX texture calls that we use
1546 // will automatically use a HW supported format.
1547 //
1548 // The most critical aim is to reduce copying; if we can use
1549 // texture-image data directly then it will be a big performance assist.
1550 //
1551
1552 switch (internalFormat) {
1553 case GL_INTENSITY:
1554 case GL_INTENSITY4:
1555 case GL_INTENSITY8:
1556 case GL_INTENSITY12:
1557 case GL_INTENSITY16:
1558 return &_mesa_texformat_l8; // D3DFMT_L8
1559 case 1:
1560 case GL_LUMINANCE:
1561 case GL_LUMINANCE4:
1562 case GL_LUMINANCE8:
1563 case GL_LUMINANCE12:
1564 case GL_LUMINANCE16:
1565 return &_mesa_texformat_l8; // D3DFMT_L8
1566 case GL_ALPHA:
1567 case GL_ALPHA4:
1568 case GL_ALPHA8:
1569 case GL_ALPHA12:
1570 case GL_ALPHA16:
1571 return &_mesa_texformat_a8; // D3DFMT_A8
1572 case GL_COLOR_INDEX:
1573 case GL_COLOR_INDEX1_EXT:
1574 case GL_COLOR_INDEX2_EXT:
1575 case GL_COLOR_INDEX4_EXT:
1576 case GL_COLOR_INDEX8_EXT:
1577 case GL_COLOR_INDEX12_EXT:
1578 case GL_COLOR_INDEX16_EXT:
1579 return &_mesa_texformat_rgb565; // D3DFMT_R5G6B5
1580 // Mesa will convert this for us later...
1581 // return &_mesa_texformat_ci8; // D3DFMT_R5G6B5
1582 case 2:
1583 case GL_LUMINANCE_ALPHA:
1584 case GL_LUMINANCE4_ALPHA4:
1585 case GL_LUMINANCE6_ALPHA2:
1586 case GL_LUMINANCE8_ALPHA8:
1587 case GL_LUMINANCE12_ALPHA4:
1588 case GL_LUMINANCE12_ALPHA12:
1589 case GL_LUMINANCE16_ALPHA16:
1590 return &_mesa_texformat_al88; // D3DFMT_A8L8
1591 case GL_R3_G3_B2:
1592 return &_mesa_texformat_rgb332; // D3DFMT_R3G3B2
1593 case GL_RGB4:
1594 case GL_RGBA4:
1595 case GL_RGBA2:
1596 return &_mesa_texformat_argb4444; // D3DFMT_A4R4G4B4
1597 case 3:
1598 case GL_RGB:
1599 case GL_RGB5:
1600 case GL_RGB8:
1601 case GL_RGB10:
1602 case GL_RGB12:
1603 case GL_RGB16:
1604 return &_mesa_texformat_rgb565;
1605 case 4:
1606 case GL_RGBA:
1607 case GL_RGBA8:
1608 case GL_RGB10_A2:
1609 case GL_RGBA12:
1610 case GL_RGBA16:
1611 return &_mesa_texformat_argb8888;
1612 case GL_RGB5_A1:
1613 return &_mesa_texformat_argb1555;
1614 default:
1615 _mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat");
1616 return NULL;
1617 }
1618 }
1619
1620 //---------------------------------------------------------------------------
1621
1622 /*
1623 // Safer(?), slower version.
1624 void gld_TexImage2D_DX7(
1625 struct gl_context *ctx,
1626 GLenum target,
1627 GLint level,
1628 GLint internalFormat,
1629 GLint width,
1630 GLint height,
1631 GLint border,
1632 GLenum format,
1633 GLenum type,
1634 const GLvoid *pixels,
1635 const struct gl_pixelstore_attrib *packing,
1636 struct gl_texture_object *tObj,
1637 struct gl_texture_image *texImage)
1638 {
1639 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1640 GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx);
1641
1642 IDirect3DTexture8 *pTex;
1643 IDirect3DSurface8 *pSurface;
1644 RECT rcSrcRect;
1645 HRESULT hr;
1646 GLint texelBytes = 4;
1647 GLvoid *tempImage;
1648
1649 if (!tObj || !texImage)
1650 return;
1651
1652 if (level == 0) {
1653 _gldAllocateTexture(ctx, tObj, texImage);
1654 }
1655
1656 pTex = (IDirect3DTexture8*)tObj->DriverData;
1657 if (!pTex)
1658 return; // Texture has not been created
1659 if (level >= IDirect3DTexture8_GetLevelCount(pTex))
1660 return; // Level does not exist
1661 hr = IDirect3DTexture8_GetSurfaceLevel(pTex, level, &pSurface);
1662 if (FAILED(hr))
1663 return; // Surface level doesn't exist (or just a plain error)
1664
1665 tempImage = MALLOC(width * height * texelBytes);
1666 if (!tempImage) {
1667 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1668 IDirect3DSurface8_Release(pSurface);
1669 return;
1670 }
1671 // unpack image, apply transfer ops and store in tempImage
1672 texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1673 &_mesa_texformat_argb8888, // dest format
1674 tempImage,
1675 width, height, 1, 0, 0, 0,
1676 width * texelBytes,
1677 0, // dstImageStride
1678 format, type, pixels, packing);
1679
1680 SetRect(&rcSrcRect, 0, 0, width, height);
1681 D3DXLoadSurfaceFromMemory(
1682 pSurface,
1683 NULL,
1684 NULL,
1685 tempImage,
1686 D3DFMT_A8R8G8B8,
1687 width * texelBytes,
1688 NULL,
1689 &rcSrcRect,
1690 D3DX_FILTER_NONE,
1691 0);
1692
1693 FREE(tempImage);
1694 IDirect3DSurface8_Release(pSurface);
1695 }
1696 */
1697
1698 //---------------------------------------------------------------------------
1699
1700 // Faster, more efficient version.
1701 // Copies subimage straight to dest texture
1702 void gld_TexImage2D_DX7(
1703 struct gl_context *ctx,
1704 GLenum target,
1705 GLint level,
1706 GLint internalFormat,
1707 GLint width,
1708 GLint height,
1709 GLint border,
1710 GLenum format,
1711 GLenum type,
1712 const GLvoid *pixels,
1713 const struct gl_pixelstore_attrib *packing,
1714 struct gl_texture_object *tObj,
1715 struct gl_texture_image *texImage)
1716 {
1717 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1718 GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx);
1719
1720 IDirectDrawSurface7 *pTex = NULL;
1721 IDirectDrawSurface7 *pSurface = NULL;
1722 HRESULT hr;
1723 DDSURFACEDESC2 ddsd;
1724 int i;
1725 DDSCAPS2 ddsCaps;
1726
1727 if (!tObj || !texImage)
1728 return;
1729
1730 // GLQUAKE FIX
1731 // Test for input alpha data with non-alpha internalformat
1732 if (((internalFormat==3) || (internalFormat==GL_RGB)) && (format==GL_RGBA)) {
1733 // Input format has alpha, but a non-alpha format has been requested.
1734 texImage->IntFormat = GL_RGBA;
1735 internalFormat = GL_RGBA;
1736 }
1737
1738 if (level == 0) {
1739 _gldAllocateTexture(ctx, tObj, texImage);
1740 }
1741
1742 pTex = (IDirectDrawSurface7*)tObj->DriverData;
1743 if (!pTex) {
1744 ASSERT(0);
1745 return; // Texture has not been created
1746 }
1747
1748 pSurface = pTex;
1749 if (level != 0) {
1750 ddsd.dwSize = sizeof(ddsd);
1751 _GLD_DX7_TEX(GetSurfaceDesc(pTex, &ddsd));
1752 if ((level > 0) && (level >= ddsd.dwMipMapCount))
1753 return; // Level does not exist
1754 ZeroMemory(&ddsCaps, sizeof(ddsCaps));
1755 for (i=0; i<level; i++) {
1756 ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1757 hr = IDirectDrawSurface7_GetAttachedSurface(
1758 pSurface,
1759 &ddsCaps,
1760 &pSurface);
1761 if (SUCCEEDED(hr)) {
1762 IDirectDrawSurface7_Release(pSurface);
1763 } else {
1764 ;
1765 }
1766 }
1767 }
1768
1769 // Lock all of surface
1770 ddsd.dwSize = sizeof(ddsd);
1771 hr = IDirectDrawSurface7_Lock(pSurface, NULL, &ddsd, 0, 0);
1772 if (FAILED(hr)) {
1773 IDirectDrawSurface7_Release(pSurface);
1774 return;
1775 }
1776
1777 // unpack image, apply transfer ops and store directly in texture
1778 texImage->TexFormat->StoreImage(
1779 ctx,
1780 2,
1781 texImage->Format,
1782 //_gldMesaFormatForD3DFormat(d3dsd.Format),
1783 _gldMesaFormatForD3DFormat(_gldD3DXFormatFromSurface(pSurface)),
1784 ddsd.lpSurface,
1785 width, height, 1, 0, 0, 0,
1786 ddsd.lPitch,
1787 0, // dstImageStride
1788 format, type, pixels, packing);
1789
1790 IDirectDrawSurface7_Unlock(pSurface, NULL);
1791 }
1792
1793 //---------------------------------------------------------------------------
1794
1795 void gld_TexImage1D_DX7(struct gl_context *ctx, GLenum target, GLint level,
1796 GLint internalFormat,
1797 GLint width, GLint border,
1798 GLenum format, GLenum type, const GLvoid *pixels,
1799 const struct gl_pixelstore_attrib *packing,
1800 struct gl_texture_object *texObj,
1801 struct gl_texture_image *texImage )
1802 {
1803 // A 1D texture is a 2D texture with a height of zero
1804 gld_TexImage2D_DX7(ctx, target, level, internalFormat, width, 1, border, format, type, pixels, packing, texObj, texImage);
1805 }
1806
1807 //---------------------------------------------------------------------------
1808
1809 /*
1810 void gld_TexSubImage2D( struct gl_context *ctx, GLenum target, GLint level,
1811 GLint xoffset, GLint yoffset,
1812 GLsizei width, GLsizei height,
1813 GLenum format, GLenum type,
1814 const GLvoid *pixels,
1815 const struct gl_pixelstore_attrib *packing,
1816 struct gl_texture_object *tObj,
1817 struct gl_texture_image *texImage )
1818 {
1819 GLD_GET_CONTEXT
1820 IDirect3DTexture8 *pTex;
1821 IDirect3DSurface8 *pSurface;
1822 D3DFORMAT d3dFormat;
1823 HRESULT hr;
1824 GLint texelBytes = 4;
1825 GLvoid *tempImage;
1826 RECT rcSrcRect;
1827 RECT rcDstRect;
1828
1829 if (!tObj || !texImage)
1830 return;
1831
1832 pTex = (IDirect3DTexture8*)tObj->DriverData;
1833 if (!pTex)
1834 return; // Texture has not been created
1835 if (level >= _GLD_DX8_TEX(GetLevelCount(pTex))
1836 return; // Level does not exist
1837 hr = _GLD_DX8_TEX(GetSurfaceLevel(pTex, level, &pSurface);
1838 if (FAILED(hr))
1839 return; // Surface level doesn't exist (or just a plain error)
1840
1841 d3dFormat = _gldGLFormatToD3DFormat(texImage->Format);
1842 tempImage = MALLOC(width * height * texelBytes);
1843 if (!tempImage) {
1844 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1845 IDirect3DSurface8_Release(pSurface);
1846 return;
1847 }
1848
1849 // unpack image, apply transfer ops and store in tempImage
1850 texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1851 &_mesa_texformat_argb8888, // dest format
1852 tempImage,
1853 width, height, 1, 0, 0, 0,
1854 width * texelBytes,
1855 0, // dstImageStride
1856 format, type, pixels, packing);
1857
1858 // Source rectangle is whole of input image
1859 SetRect(&rcSrcRect, 0, 0, width, height);
1860
1861 // Dest rectangle must be offset to dest image
1862 SetRect(&rcDstRect, 0, 0, width, height);
1863 OffsetRect(&rcDstRect, xoffset, yoffset);
1864
1865 D3DXLoadSurfaceFromMemory(
1866 pSurface,
1867 NULL,
1868 &rcDstRect,
1869 tempImage,
1870 D3DFMT_A8R8G8B8,
1871 width * texelBytes,
1872 NULL,
1873 &rcSrcRect,
1874 D3DX_FILTER_NONE,
1875 0);
1876
1877 FREE(tempImage);
1878 IDirect3DSurface8_Release(pSurface);
1879 }
1880 */
1881
1882 //---------------------------------------------------------------------------
1883
1884 // Faster, more efficient version.
1885 // Copies subimage straight to dest texture
1886 void gld_TexSubImage2D_DX7( struct gl_context *ctx, GLenum target, GLint level,
1887 GLint xoffset, GLint yoffset,
1888 GLsizei width, GLsizei height,
1889 GLenum format, GLenum type,
1890 const GLvoid *pixels,
1891 const struct gl_pixelstore_attrib *packing,
1892 struct gl_texture_object *tObj,
1893 struct gl_texture_image *texImage )
1894 {
1895 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1896 GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx);
1897
1898 IDirectDrawSurface7 *pTex;
1899 IDirectDrawSurface7 *pSurface;
1900 HRESULT hr;
1901 RECT rcDstRect;
1902 DDSURFACEDESC2 ddsd;
1903 int i;
1904 DDSCAPS2 ddsCaps;
1905
1906 if (!tObj || !texImage)
1907 return;
1908
1909 pTex = (IDirectDrawSurface7*)tObj->DriverData;
1910 if (!pTex)
1911 return; // Texture has not been created
1912
1913 __try {
1914
1915 ddsd.dwSize = sizeof(ddsd);
1916 _GLD_DX7_TEX(GetSurfaceDesc(pTex, &ddsd));
1917 if ((level > 0) && (level >= ddsd.dwMipMapCount))
1918 return; // Level does not exist
1919
1920 ZeroMemory(&ddsCaps, sizeof(ddsCaps));
1921 pSurface = pTex;
1922 for (i=0; i<level; i++) {
1923 ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
1924 hr = IDirectDrawSurface7_GetAttachedSurface(
1925 pSurface,
1926 &ddsCaps,
1927 &pSurface);
1928 if(SUCCEEDED(hr)) {
1929 IDirectDrawSurface7_Release(pSurface);
1930 } else {
1931 return;
1932 }
1933 }
1934
1935 // Dest rectangle must be offset to dest image
1936 SetRect(&rcDstRect, 0, 0, width, height);
1937 OffsetRect(&rcDstRect, xoffset, yoffset);
1938
1939 // Lock sub-rect of surface
1940 hr = IDirectDrawSurface7_Lock(pSurface, &rcDstRect, &ddsd, 0, 0);
1941 if (FAILED(hr)) {
1942 IDirectDrawSurface7_Release(pSurface);
1943 return;
1944 }
1945
1946 // unpack image, apply transfer ops and store directly in texture
1947 texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1948 _gldMesaFormatForD3DFormat(_gldD3DXFormatFromSurface(pSurface)),
1949 ddsd.lpSurface,
1950 width, height, 1,
1951 0, 0, 0, // NOTE: d3dLockedRect.pBits is already offset!!!
1952 ddsd.lPitch,
1953 0, // dstImageStride
1954 format, type, pixels, packing);
1955
1956
1957 IDirectDrawSurface7_Unlock(pSurface, &rcDstRect);
1958 }
1959 __except(EXCEPTION_EXECUTE_HANDLER) {
1960 ;
1961 }
1962 }
1963
1964 //---------------------------------------------------------------------------
1965
1966 void gld_TexSubImage1D_DX7( struct gl_context *ctx, GLenum target, GLint level,
1967 GLint xoffset, GLsizei width,
1968 GLenum format, GLenum type,
1969 const GLvoid *pixels,
1970 const struct gl_pixelstore_attrib *packing,
1971 struct gl_texture_object *texObj,
1972 struct gl_texture_image *texImage )
1973 {
1974 gld_TexSubImage2D_DX7(ctx, target, level, xoffset, 0, width, 1, format, type, pixels, packing, texObj, texImage);
1975 }
1976
1977 //---------------------------------------------------------------------------
1978
1979 void gld_DeleteTexture_DX7(
1980 struct gl_context *ctx,
1981 struct gl_texture_object *tObj)
1982 {
1983 GLD_context *gld = (GLD_context*)(ctx->DriverCtx);
1984
1985 __try {
1986
1987 if (tObj) {
1988 IDirectDrawSurface7 *pTex = (IDirectDrawSurface7*)tObj->DriverData;
1989 if (pTex) {
1990 /* // Make sure texture is not bound to a stage before releasing it
1991 for (int i=0; i<MAX_TEXTURE_UNITS; i++) {
1992 if (gld->CurrentTexture[i] == pTex) {
1993 gld->pDev->SetTexture(i, NULL);
1994 gld->CurrentTexture[i] = NULL;
1995 }
1996 }*/
1997 _GLD_DX7_TEX(Release(pTex));
1998 tObj->DriverData = NULL;
1999 }
2000 }
2001
2002 }
2003 __except(EXCEPTION_EXECUTE_HANDLER) {
2004 ;
2005 }
2006 }
2007
2008 //---------------------------------------------------------------------------
2009
2010 __inline void _gldSetColorOps(
2011 const GLD_driver_dx7 *gld,
2012 GLuint unit,
2013 DWORD ColorArg1,
2014 D3DTEXTUREOP ColorOp,
2015 DWORD ColorArg2)
2016 {
2017 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG1, ColorArg1));
2018 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLOROP, ColorOp));
2019 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG2, ColorArg2));
2020 }
2021
2022 //---------------------------------------------------------------------------
2023
2024 __inline void _gldSetAlphaOps(
2025 const GLD_driver_dx7 *gld,
2026 GLuint unit,
2027 DWORD AlphaArg1,
2028 D3DTEXTUREOP AlphaOp,
2029 DWORD AlphaArg2)
2030 {
2031 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG1, AlphaArg1));
2032 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAOP, AlphaOp));
2033 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ALPHAARG2, AlphaArg2));
2034 }
2035
2036 //---------------------------------------------------------------------------
2037
2038 void gldUpdateTextureUnit(
2039 struct gl_context *ctx,
2040 GLuint unit,
2041 BOOL bPassThrough)
2042 {
2043 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
2044 GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx);
2045
2046 D3DTEXTUREMINFILTER minfilter;
2047 D3DTEXTUREMIPFILTER mipfilter;
2048 GLenum BaseFormat;
2049 DWORD dwColorArg0;
2050 int iTexEnv = 0;
2051 GLD_texenv *pTexenv;
2052
2053 // NOTE: If bPassThrough is FALSE then texture stage can be
2054 // disabled otherwise it must pass-through it's current fragment.
2055
2056 const struct gl_texture_unit *pUnit = &ctx->Texture.Unit[unit];
2057 const struct gl_texture_object *tObj = pUnit->_Current;
2058
2059 IDirectDrawSurface7 *pTex = NULL;
2060 if (tObj) {
2061 pTex = (IDirectDrawSurface7*)tObj->DriverData;
2062 }
2063
2064 __try {
2065
2066 // Enable texturing if unit is enabled and a valid D3D texture exists
2067 // Mesa 5: TEXTUREn_x altered to TEXTURE_nD_BIT
2068 //if (pTex && (pUnit->Enabled & (TEXTURE0_1D | TEXTURE0_2D))) {
2069 if (pTex && (pUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT))) {
2070 // Enable texturing
2071 _GLD_DX7_DEV(SetTexture(gld->pDev, unit, pTex));
2072 } else {
2073 // Disable texturing, then return
2074 _GLD_DX7_DEV(SetTexture(gld->pDev, unit, NULL));
2075 if (bPassThrough) {
2076 _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE);
2077 _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE);
2078 } else {
2079 _gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE);
2080 _gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE);
2081 }
2082 return;
2083 }
2084
2085 // Texture parameters
2086 _gldConvertMinFilter(tObj->MinFilter, &minfilter, &mipfilter);
2087 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MINFILTER, minfilter));
2088 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MIPFILTER, mipfilter));
2089 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_MAGFILTER, _gldConvertMagFilter(tObj->MagFilter)));
2090 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSU, _gldConvertWrap(tObj->WrapS)));
2091 _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_ADDRESSV, _gldConvertWrap(tObj->WrapT)));
2092
2093 // Texture priority
2094 _GLD_DX7_TEX(SetPriority(pTex, (DWORD)(tObj->Priority*65535.0f)));
2095
2096 // Texture environment
2097 // TODO: Examine input texture for alpha and use specific alpha/non-alpha ops.
2098 // See Page 355 of the Red Book.
2099 BaseFormat = _gldDecodeBaseFormat(pTex);
2100
2101 switch (BaseFormat) {
2102 case GL_RGB:
2103 iTexEnv = 0;
2104 break;
2105 case GL_RGBA:
2106 iTexEnv = 1;
2107 break;
2108 case GL_ALPHA:
2109 iTexEnv = 2;
2110 break;
2111 }
2112
2113 switch (pUnit->EnvMode) {
2114 case GL_DECAL:
2115 iTexEnv += 0;
2116 break;
2117 case GL_REPLACE:
2118 iTexEnv += 3;
2119 break;
2120 case GL_MODULATE:
2121 iTexEnv += 6;
2122 break;
2123 case GL_BLEND:
2124 // Set blend colour
2125 // Unsupported by DX7
2126 // dwColorArg0 = D3DCOLOR_COLORVALUE(pUnit->EnvColor[0], pUnit->EnvColor[1], pUnit->EnvColor[2], pUnit->EnvColor[3]);
2127 // _GLD_DX7_DEV(SetTextureStageState(gld->pDev, unit, D3DTSS_COLORARG0, dwColorArg0));
2128 // gldLogMessage(GLDLOG_WARN, "GL_BLEND\n");
2129 iTexEnv += 9;
2130 break;
2131 case GL_ADD:
2132 iTexEnv += 12;
2133 break;
2134 }
2135 pTexenv = (GLD_texenv*)&gldTexEnv[iTexEnv];
2136 _gldSetColorOps(gld, unit, pTexenv->ColorArg1, pTexenv->ColorOp, pTexenv->ColorArg2);
2137 _gldSetAlphaOps(gld, unit, pTexenv->AlphaArg1, pTexenv->AlphaOp, pTexenv->AlphaArg2);
2138
2139 }
2140 __except(EXCEPTION_EXECUTE_HANDLER) {
2141 ;
2142 }
2143 }
2144
2145 //---------------------------------------------------------------------------
2146
2147 void gld_NEW_TEXTURE_DX7(
2148 struct gl_context *ctx)
2149 {
2150 // TODO: Support for three (ATI Radeon) or more (nVidia GeForce3) texture units
2151
2152 BOOL bUnit0Enabled;
2153 BOOL bUnit1Enabled;
2154
2155 if (!ctx)
2156 return; // Sanity check
2157
2158 if (ctx->Const.MaxTextureUnits == 1) {
2159 gldUpdateTextureUnit(ctx, 0, TRUE);
2160 return;
2161 }
2162
2163 //
2164 // NOTE: THE FOLLOWING RELATES TO TWO TEXTURE UNITS, AND TWO ONLY!!
2165 //
2166
2167 // Mesa 5: Texture Units altered
2168 bUnit0Enabled = (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE;
2169 bUnit1Enabled = (ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) ? TRUE : FALSE;
2170
2171 // If Unit0 is disabled and Unit1 is enabled then we must pass-though
2172 gldUpdateTextureUnit(ctx, 0, (!bUnit0Enabled && bUnit1Enabled) ? TRUE : FALSE);
2173 // We can always disable the last texture unit
2174 gldUpdateTextureUnit(ctx, 1, FALSE);
2175
2176 #ifdef _DEBUG
2177 {
2178 // Find out whether device supports current renderstates
2179 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
2180 GLD_driver_dx7 *gld = GLD_GET_DX7_DRIVER(gldCtx);
2181
2182 DWORD dwPasses;
2183 _GLD_DX7_DEV(ValidateDevice(gld->pDev, &dwPasses));
2184 #if 0
2185 if (FAILED(hr)) {
2186 gldLogError(GLDLOG_ERROR, "ValidateDevice failed", hr);
2187 }
2188 #endif
2189 if (dwPasses != 1) {
2190 gldLogMessage(GLDLOG_ERROR, "ValidateDevice: Can't do in one pass\n");
2191 }
2192 }
2193 #endif
2194 };
2195
2196 //---------------------------------------------------------------------------