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