1
/****************************************************************************
3
* Mesa 3-D graphics library
4
* Direct3D Driver Interface
6
* ========================================================================
8
* Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
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:
17
* The above copyright notice and this permission notice shall be included
18
* in all copies or substantial portions of the Software.
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
28
* ======================================================================
31
* Environment: Windows 9x/2000/XP/XBox (Win32)
33
* Description: Texture / Bitmap functions
35
****************************************************************************/
37
#include "dglcontext.h"
43
#include "texformat.h"
49
//---------------------------------------------------------------------------
51
#define GLD_FLIP_HEIGHT(y,h) (gldCtx->dwHeight - (y) - (h))
53
//---------------------------------------------------------------------------
55
//---------------------------------------------------------------------------
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))
66
//---------------------------------------------------------------------------
68
static void gld_fetch_1d_texel_X8R8G8B8(
69
const struct gl_texture_image *texImage,
70
GLint i, GLint j, GLint k, GLchan *texel )
72
const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
73
GLchan *rgba = (GLchan *)texel;
77
rgba[ACOMP] = CHAN_MAX;
80
//---------------------------------------------------------------------------
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 )
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]);
93
//---------------------------------------------------------------------------
95
static void gld_fetch_1d_texel_X1R5G5B5(
96
const struct gl_texture_image *texImage,
97
GLint i, GLint j, GLint k, GLchan *texel )
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;
107
//---------------------------------------------------------------------------
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 )
113
const GLushort *src = USHORT_SRC( texImage, i, j, k );
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 );
121
//---------------------------------------------------------------------------
123
static void gld_fetch_1d_texel_X4R4G4B4(
124
const struct gl_texture_image *texImage,
125
GLint i, GLint j, GLint k, GLchan *texel )
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;
135
//---------------------------------------------------------------------------
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 )
141
const GLushort *src = USHORT_SRC( texImage, i, j, k );
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 );
149
//---------------------------------------------------------------------------
156
//---------------------------------------------------------------------------
158
//---------------------------------------------------------------------------
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)))
169
//---------------------------------------------------------------------------
171
static void gld_fetch_2d_texel_X8R8G8B8(
172
const struct gl_texture_image *texImage,
173
GLint i, GLint j, GLint k, GLchan *texel )
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;
183
//---------------------------------------------------------------------------
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 )
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]);
196
//---------------------------------------------------------------------------
198
static void gld_fetch_2d_texel_X1R5G5B5(
199
const struct gl_texture_image *texImage,
200
GLint i, GLint j, GLint k, GLchan *texel )
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;
210
//---------------------------------------------------------------------------
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 )
216
const GLushort *src = USHORT_SRC( texImage, i, j, k );
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 );
224
//---------------------------------------------------------------------------
226
static void gld_fetch_2d_texel_X4R4G4B4(
227
const struct gl_texture_image *texImage,
228
GLint i, GLint j, GLint k, GLchan *texel )
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;
238
//---------------------------------------------------------------------------
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 )
244
const GLushort *src = USHORT_SRC( texImage, i, j, k );
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 );
252
//---------------------------------------------------------------------------
259
//---------------------------------------------------------------------------
261
//---------------------------------------------------------------------------
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)) * \
272
#define FLOAT_SRC( t, i, j, k ) \
273
((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) * \
276
//---------------------------------------------------------------------------
278
static void gld_fetch_3d_texel_X8R8G8B8(
279
const struct gl_texture_image *texImage,
280
GLint i, GLint j, GLint k, GLchan *texel )
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;
290
//---------------------------------------------------------------------------
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 )
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]);
303
//---------------------------------------------------------------------------
305
static void gld_fetch_3d_texel_X1R5G5B5(
306
const struct gl_texture_image *texImage,
307
GLint i, GLint j, GLint k, GLchan *texel )
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;
317
//---------------------------------------------------------------------------
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 )
323
const GLushort *src = USHORT_SRC( texImage, i, j, k );
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 );
331
//---------------------------------------------------------------------------
333
static void gld_fetch_3d_texel_X4R4G4B4(
334
const struct gl_texture_image *texImage,
335
GLint i, GLint j, GLint k, GLchan *texel )
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;
345
//---------------------------------------------------------------------------
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 )
351
const GLushort *src = USHORT_SRC( texImage, i, j, k );
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 );
359
//---------------------------------------------------------------------------
366
//---------------------------------------------------------------------------
367
// Direct3D texture formats that have no Mesa equivalent
368
//---------------------------------------------------------------------------
370
const struct gl_texture_format _gld_texformat_X8R8G8B8 = {
371
MESA_FORMAT_ARGB8888, /* MesaFormat */
372
GL_RGBA, /* BaseFormat */
373
GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
378
0, /* LuminanceBits */
379
0, /* IntensityBits */
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 */
392
const struct gl_texture_format _gld_texformat_X1R5G5B5 = {
393
MESA_FORMAT_ARGB1555, /* MesaFormat */
394
GL_RGBA, /* BaseFormat */
395
GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
400
0, /* LuminanceBits */
401
0, /* IntensityBits */
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 */
414
const struct gl_texture_format _gld_texformat_X4R4G4B4 = {
415
MESA_FORMAT_ARGB4444, /* MesaFormat */
416
GL_RGBA, /* BaseFormat */
417
GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
422
0, /* LuminanceBits */
423
0, /* IntensityBits */
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 */
436
//---------------------------------------------------------------------------
437
// Texture unit constants
438
//---------------------------------------------------------------------------
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
459
// Per-stage (i.e. per-unit) texture environment
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
469
// TODO: Do we really need to set ARG1 and ARG2 every time?
470
// They seem to always be TEXTURE and CURRENT respectively.
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},
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},
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},
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},
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},
531
//---------------------------------------------------------------------------
533
D3DTEXTUREADDRESS _gldConvertWrap(
536
return (wrap == GL_CLAMP) ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP;
539
//---------------------------------------------------------------------------
541
D3DTEXTUREFILTERTYPE _gldConvertMagFilter(
544
return (magfilter == GL_LINEAR) ? D3DTEXF_LINEAR : D3DTEXF_POINT;
547
//---------------------------------------------------------------------------
549
void _gldConvertMinFilter(
551
D3DTEXTUREFILTERTYPE *min_filter,
552
D3DTEXTUREFILTERTYPE *mip_filter)
556
*min_filter = D3DTEXF_POINT;
557
*mip_filter = D3DTEXF_NONE;
560
*min_filter = D3DTEXF_LINEAR;
561
*mip_filter = D3DTEXF_NONE;
563
case GL_NEAREST_MIPMAP_NEAREST:
564
*min_filter = D3DTEXF_POINT;
565
*mip_filter = D3DTEXF_POINT;
567
case GL_LINEAR_MIPMAP_NEAREST:
568
*min_filter = D3DTEXF_LINEAR;
569
*mip_filter = D3DTEXF_POINT;
571
case GL_NEAREST_MIPMAP_LINEAR:
572
*min_filter = D3DTEXF_POINT;
573
*mip_filter = D3DTEXF_LINEAR;
575
case GL_LINEAR_MIPMAP_LINEAR:
576
*min_filter = D3DTEXF_LINEAR;
577
*mip_filter = D3DTEXF_LINEAR;
582
//---------------------------------------------------------------------------
584
D3DFORMAT _gldGLFormatToD3DFormat(
585
GLenum internalFormat)
587
switch (internalFormat) {
593
// LUNIMANCE != INTENSITY, but D3D doesn't have I8 textures
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;
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:
626
// TODO: Mesa does not support RGB332 internally
627
return D3DFMT_X4R4G4B4; //D3DFMT_R3G3B2;
629
return D3DFMT_X4R4G4B4;
631
return D3DFMT_X1R5G5B5;
638
return D3DFMT_R8G8B8;
640
return D3DFMT_A4R4G4B4;
648
return D3DFMT_A8R8G8B8;
650
return D3DFMT_A1R5G5B5;
653
// Return an acceptable default
654
return D3DFMT_A8R8G8B8;
657
//---------------------------------------------------------------------------
659
GLenum _gldDecodeBaseFormat(
660
IDirect3DTexture8 *pTex)
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().
666
// Base internal format is one of (Red Book p355):
669
// GL_LUMINANCE_ALPHA,
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
678
// TODO: cache format instead of using GetLevelDesc()
679
D3DSURFACE_DESC desc;
680
_GLD_DX8_TEX(GetLevelDesc(pTex, 0, &desc));
682
switch (desc.Format) {
684
case D3DFMT_X8R8G8B8:
686
case D3DFMT_X1R5G5B5:
688
case D3DFMT_X4R4G4B4:
692
case D3DFMT_A8R8G8B8:
693
case D3DFMT_A1R5G5B5:
694
case D3DFMT_A4R4G4B4:
695
case D3DFMT_A8R3G3B2:
702
// Compressed texture formats. Need to check these...
715
// Fell through. Return arbitary default.
719
//---------------------------------------------------------------------------
721
const struct gl_texture_format* _gldMesaFormatForD3DFormat(
725
case D3DFMT_A8R8G8B8:
726
return &_mesa_texformat_argb8888;
728
return &_mesa_texformat_rgb888;
730
return &_mesa_texformat_rgb565;
731
case D3DFMT_A4R4G4B4:
732
return &_mesa_texformat_argb4444;
733
case D3DFMT_A1R5G5B5:
734
return &_mesa_texformat_argb1555;
736
return &_mesa_texformat_al88;
738
return &_mesa_texformat_rgb332;
740
return &_mesa_texformat_a8;
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;
751
// If we reach here then we've made an error somewhere else
752
// by allowing a format that is not supported.
755
return NULL; // Shut up compiler warning
758
//---------------------------------------------------------------------------
760
//---------------------------------------------------------------------------
762
void gldCopyTexImage1D_DX8(
764
GLenum target, GLint level,
765
GLenum internalFormat,
767
GLsizei width, GLint border )
772
//---------------------------------------------------------------------------
774
void gldCopyTexImage2D_DX8(
778
GLenum internalFormat,
788
//---------------------------------------------------------------------------
790
void gldCopyTexSubImage1D_DX8(
792
GLenum target, GLint level,
793
GLint xoffset, GLint x, GLint y, GLsizei width )
798
//---------------------------------------------------------------------------
800
void gldCopyTexSubImage2D_DX8(
814
//---------------------------------------------------------------------------
816
void gldCopyTexSubImage3D_DX8(
831
//---------------------------------------------------------------------------
832
// Bitmap/Pixel functions
833
//---------------------------------------------------------------------------
835
#define GLD_FLIP_Y(y) (gldCtx->dwHeight - (y))
837
#define _GLD_FVF_IMAGE (D3DFVF_XYZRHW | D3DFVF_TEX1)
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
846
//---------------------------------------------------------------------------
848
HRESULT _gldDrawPixels(
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)
858
// Draw input image as texture implementing PixelZoom and clipping.
859
// Any fragment operations currently enabled will be used.
862
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
863
GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx);
865
IDirect3DTexture8 *pTexture;
866
D3DSURFACE_DESC d3dsd;
867
IDirect3DSurface8 *pSurface;
868
_GLD_IMAGE_VERTEX v[4];
871
float ZoomWidth, ZoomHeight;
872
float ScaleWidth, ScaleHeight;
874
// Create a texture to hold image
875
hr = D3DXCreateTexture(
880
D3DFMT_A8R8G8B8, // format
881
D3DPOOL_MANAGED, // pool
886
hr = IDirect3DTexture8_GetSurfaceLevel(pTexture, 0, &pSurface);
888
IDirect3DTexture8_Release(pTexture);
892
// Copy image into texture
893
hr = D3DXLoadSurfaceFromSurface(
894
pSurface, NULL, NULL, // Dest surface
895
pImage, NULL, NULL, // Src surface
898
IDirect3DSurface8_Release(pSurface);
900
IDirect3DTexture8_Release(pTexture);
905
// Set up the quad like this (ascii-art ahead!)
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;
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;
929
// Set raster positions
930
ZoomWidth = (float)width * ctx->Pixel.ZoomX;
931
ZoomHeight = (float)height * ctx->Pixel.ZoomY;
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);
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);
957
// Emulate Chromakey with an Alpha Test.
958
// [Alpha Test is more widely supported anyway]
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);
970
IDirect3DDevice8_DrawPrimitiveUP(gld->pDev, D3DPT_TRIANGLEFAN, 2, &v, sizeof(_GLD_IMAGE_VERTEX));
973
IDirect3DDevice8_SetTexture(gld->pDev, 0, NULL);
974
IDirect3DTexture8_Release(pTexture);
976
// Reset state to before we messed it up
977
FLUSH_VERTICES(ctx, _NEW_ALL);
982
//---------------------------------------------------------------------------
984
void gld_DrawPixels_DX8(
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 )
994
IDirect3DSurface8 *pImage;
996
D3DLOCKED_RECT d3dLockedRect;
998
const struct gl_texture_format *MesaFormat;
1000
gldCtx = GLD_GET_CONTEXT(ctx);
1001
gld = GLD_GET_DX8_DRIVER(gldCtx);
1003
hr = IDirect3DDevice8_CreateImageSurface(
1014
// Use Mesa to fill in image
1017
// Lock all of surface
1018
hr = IDirect3DSurface8_LockRect(pImage, &d3dLockedRect, NULL, 0);
1020
IDirect3DSurface8_Release(pImage);
1024
MesaFormat = _mesa_choose_tex_format(ctx, format, format, type);
1026
// unpack image, apply transfer ops and store directly in texture
1027
MesaFormat->StoreImage(
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);
1038
IDirect3DSurface8_UnlockRect(pImage);
1040
_gldDrawPixels(ctx, FALSE, x, y, width, height, pImage);
1042
IDirect3DSurface8_Release(pImage);
1045
//---------------------------------------------------------------------------
1047
void gld_ReadPixels_DX8(
1049
GLint x, GLint y, GLsizei width, GLsizei height,
1050
GLenum format, GLenum type,
1051
const struct gl_pixelstore_attrib *pack,
1055
GLD_context *gldCtx;
1056
GLD_driver_dx8 *gld;
1058
IDirect3DSurface8 *pBackbuffer = NULL;
1059
IDirect3DSurface8 *pNativeImage = NULL;
1060
IDirect3DSurface8 *pCanonicalImage = NULL;
1062
D3DSURFACE_DESC d3dsd;
1063
RECT rcSrc; // Source rect
1064
POINT ptDst; // Dest point
1066
D3DLOCKED_RECT d3dLockedRect;
1067
struct gl_pixelstore_attrib srcPacking;
1070
const struct gl_texture_format *MesaFormat;
1073
case GL_STENCIL_INDEX:
1074
case GL_DEPTH_COMPONENT:
1078
MesaFormat = _mesa_choose_tex_format(ctx, format, format, type);
1079
DstRowStride = _mesa_image_row_stride(pack, width, format, type);
1081
gldCtx = GLD_GET_CONTEXT(ctx);
1082
gld = GLD_GET_DX8_DRIVER(gldCtx);
1085
hr = IDirect3DDevice8_GetBackBuffer(
1087
0, // First backbuffer
1088
D3DBACKBUFFER_TYPE_MONO,
1093
// Get backbuffer description
1094
hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd);
1096
goto gld_ReadPixels_DX8_return;
1099
// Create a surface compatible with backbuffer
1100
hr = IDirect3DDevice8_CreateImageSurface(
1107
goto gld_ReadPixels_DX8_return;
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;
1115
// Get source pixels.
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.
1121
hr = IDirect3DDevice8_CopyRects(
1129
goto gld_ReadPixels_DX8_return;
1132
// Create an RGBA8888 surface
1133
hr = IDirect3DDevice8_CreateImageSurface(
1140
goto gld_ReadPixels_DX8_return;
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
1152
goto gld_ReadPixels_DX8_return;
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;
1164
// Lock all of image
1165
hr = IDirect3DSurface8_LockRect(pCanonicalImage, &d3dLockedRect, NULL, 0);
1167
goto gld_ReadPixels_DX8_return;
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(
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
1190
IDirect3DSurface8_UnlockRect(pCanonicalImage);
1192
gld_ReadPixels_DX8_return:
1193
SAFE_RELEASE_SURFACE8(pCanonicalImage);
1194
SAFE_RELEASE_SURFACE8(pNativeImage);
1195
SAFE_RELEASE_SURFACE8(pBackbuffer);
1198
//---------------------------------------------------------------------------
1200
void gld_CopyPixels_DX8(
1211
// NOTE: Not allowed to copy vidmem to vidmem!
1212
// Therefore we use an intermediate image surface.
1215
GLD_context *gldCtx;
1216
GLD_driver_dx8 *gld;
1218
IDirect3DSurface8 *pBackbuffer;
1219
D3DSURFACE_DESC d3dsd;
1220
IDirect3DSurface8 *pImage;
1221
RECT rcSrc; // Source rect
1222
POINT ptDst; // Dest point
1226
if (type != GL_COLOR)
1229
gldCtx = GLD_GET_CONTEXT(ctx);
1230
gld = GLD_GET_DX8_DRIVER(gldCtx);
1233
hr = IDirect3DDevice8_GetBackBuffer(
1235
0, // First backbuffer
1236
D3DBACKBUFFER_TYPE_MONO,
1241
// Get backbuffer description
1242
hr = IDirect3DSurface8_GetDesc(pBackbuffer, &d3dsd);
1244
IDirect3DSurface8_Release(pBackbuffer);
1248
// Create a surface compatible with backbuffer
1249
hr = IDirect3DDevice8_CreateImageSurface(
1256
IDirect3DSurface8_Release(pBackbuffer);
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;
1265
// Get source pixels
1266
hr = IDirect3DDevice8_CopyRects(
1273
IDirect3DSurface8_Release(pBackbuffer);
1275
IDirect3DSurface8_Release(pImage);
1279
_gldDrawPixels(ctx, FALSE, dstx, dsty, width, height, pImage);
1281
IDirect3DSurface8_Release(pImage);
1284
//---------------------------------------------------------------------------
1286
void gld_Bitmap_DX8(
1292
const struct gl_pixelstore_attrib *unpack,
1293
const GLubyte *bitmap)
1295
GLD_context *gldCtx;
1296
GLD_driver_dx8 *gld;
1298
IDirect3DSurface8 *pImage;
1300
D3DLOCKED_RECT d3dLockedRect;
1302
D3DCOLOR clBitmapOne, clBitmapZero;
1307
gldCtx = GLD_GET_CONTEXT(ctx);
1308
gld = GLD_GET_DX8_DRIVER(gldCtx);
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
1317
hr = IDirect3DDevice8_CreateImageSurface(
1327
// Lock all of surface
1328
hr = IDirect3DSurface8_LockRect(pImage, &d3dLockedRect, NULL, 0);
1330
IDirect3DSurface8_Release(pImage);
1334
pTempBitmap = _mesa_unpack_bitmap(width, height, bitmap, unpack);
1335
if (pTempBitmap == NULL) {
1336
IDirect3DSurface8_Release(pImage);
1340
pBits = (D3DCOLOR*)d3dLockedRect.pBits;
1342
for (i=0; i<height; i++) {
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,
1348
for (j=0; j<(width>>3); j++) {
1350
for (k=0; k<8; k++) {
1351
*pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero;
1355
// Fill remaining bits from bitmap
1358
for (k=0; k<(width & 7); k++) {
1359
*pBits++ = (byte & 128) ? clBitmapOne : clBitmapZero;
1368
// unpack image, apply transfer ops and store directly in texture
1369
texImage->TexFormat->StoreImage(
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);
1380
IDirect3DSurface8_UnlockRect(pImage);
1382
_gldDrawPixels(ctx, TRUE, x, y, width, height, pImage);
1384
IDirect3DSurface8_Release(pImage);
1387
//---------------------------------------------------------------------------
1388
// Texture functions
1389
//---------------------------------------------------------------------------
1391
void _gldAllocateTexture(
1393
struct gl_texture_object *tObj,
1394
struct gl_texture_image *texImage)
1396
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1397
GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx);
1399
IDirect3DTexture8 *pTex;
1400
D3DFORMAT d3dFormat;
1402
if (!tObj || !texImage)
1405
pTex = (IDirect3DTexture8*)tObj->DriverData;
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))
1415
return; // Keep the existing texture
1417
tObj->DriverData = NULL;
1418
_GLD_DX8_TEX(Release(pTex));
1421
d3dFormat = _gldGLFormatToD3DFormat(texImage->IntFormat);
1426
// TODO: Re-evaluate mipmapping
1427
(glb.bUseMipmaps) ? D3DX_DEFAULT : 1,
1432
tObj->DriverData = pTex;
1435
//---------------------------------------------------------------------------
1437
const struct gl_texture_format* gld_ChooseTextureFormat_DX8(
1439
GLint internalFormat,
1443
// [Based on mesa_choose_tex_format()]
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.
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.
1454
switch (internalFormat) {
1458
case GL_INTENSITY12:
1459
case GL_INTENSITY16:
1460
return &_mesa_texformat_l8; // D3DFMT_L8
1465
case GL_LUMINANCE12:
1466
case GL_LUMINANCE16:
1467
return &_mesa_texformat_l8; // D3DFMT_L8
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
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
1494
return &_mesa_texformat_rgb332; // D3DFMT_R3G3B2
1498
return &_mesa_texformat_argb4444; // D3DFMT_A4R4G4B4
1506
return &_mesa_texformat_rgb565;
1513
return &_mesa_texformat_argb8888;
1515
return &_mesa_texformat_argb1555;
1517
_mesa_problem(NULL, "unexpected format in fxDDChooseTextureFormat");
1522
//---------------------------------------------------------------------------
1525
// Safer(?), slower version.
1526
void gld_TexImage2D_DX8(
1530
GLint internalFormat,
1536
const GLvoid *pixels,
1537
const struct gl_pixelstore_attrib *packing,
1538
struct gl_texture_object *tObj,
1539
struct gl_texture_image *texImage)
1541
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1542
GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx);
1544
IDirect3DTexture8 *pTex;
1545
IDirect3DSurface8 *pSurface;
1548
GLint texelBytes = 4;
1551
if (!tObj || !texImage)
1555
_gldAllocateTexture(ctx, tObj, texImage);
1558
pTex = (IDirect3DTexture8*)tObj->DriverData;
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);
1565
return; // Surface level doesn't exist (or just a plain error)
1567
tempImage = MALLOC(width * height * texelBytes);
1569
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1570
IDirect3DSurface8_Release(pSurface);
1573
// unpack image, apply transfer ops and store in tempImage
1574
texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1575
&_mesa_texformat_argb8888, // dest format
1577
width, height, 1, 0, 0, 0,
1579
0, // dstImageStride
1580
format, type, pixels, packing);
1582
SetRect(&rcSrcRect, 0, 0, width, height);
1583
D3DXLoadSurfaceFromMemory(
1596
IDirect3DSurface8_Release(pSurface);
1600
//---------------------------------------------------------------------------
1602
// Faster, more efficient version.
1603
// Copies subimage straight to dest texture
1604
void gld_TexImage2D_DX8(
1608
GLint internalFormat,
1614
const GLvoid *pixels,
1615
const struct gl_pixelstore_attrib *packing,
1616
struct gl_texture_object *tObj,
1617
struct gl_texture_image *texImage)
1619
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1620
GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx);
1622
IDirect3DTexture8 *pTex;
1623
IDirect3DSurface8 *pSurface;
1625
D3DLOCKED_RECT d3dLockedRect;
1626
D3DSURFACE_DESC d3dsd;
1628
if (!tObj || !texImage)
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;
1640
_gldAllocateTexture(ctx, tObj, texImage);
1643
pTex = (IDirect3DTexture8*)tObj->DriverData;
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);
1650
return; // Surface level doesn't exist (or just a plain error)
1652
IDirect3DSurface8_GetDesc(pSurface, &d3dsd);
1654
// Lock all of surface
1655
hr = IDirect3DSurface8_LockRect(pSurface, &d3dLockedRect, NULL, 0);
1657
IDirect3DSurface8_Release(pSurface);
1661
// unpack image, apply transfer ops and store directly in texture
1662
texImage->TexFormat->StoreImage(
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);
1673
IDirect3DSurface8_UnlockRect(pSurface);
1674
IDirect3DSurface8_Release(pSurface);
1677
//---------------------------------------------------------------------------
1679
void gld_TexImage1D_DX8(GLcontext *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 )
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);
1691
//---------------------------------------------------------------------------
1694
void gld_TexSubImage2D( GLcontext *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 )
1704
IDirect3DTexture8 *pTex;
1705
IDirect3DSurface8 *pSurface;
1706
D3DFORMAT d3dFormat;
1708
GLint texelBytes = 4;
1713
if (!tObj || !texImage)
1716
pTex = (IDirect3DTexture8*)tObj->DriverData;
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);
1723
return; // Surface level doesn't exist (or just a plain error)
1725
d3dFormat = _gldGLFormatToD3DFormat(texImage->Format);
1726
tempImage = MALLOC(width * height * texelBytes);
1728
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1729
IDirect3DSurface8_Release(pSurface);
1733
// unpack image, apply transfer ops and store in tempImage
1734
texImage->TexFormat->StoreImage(ctx, 2, texImage->Format,
1735
&_mesa_texformat_argb8888, // dest format
1737
width, height, 1, 0, 0, 0,
1739
0, // dstImageStride
1740
format, type, pixels, packing);
1742
// Source rectangle is whole of input image
1743
SetRect(&rcSrcRect, 0, 0, width, height);
1745
// Dest rectangle must be offset to dest image
1746
SetRect(&rcDstRect, 0, 0, width, height);
1747
OffsetRect(&rcDstRect, xoffset, yoffset);
1749
D3DXLoadSurfaceFromMemory(
1762
IDirect3DSurface8_Release(pSurface);
1766
//---------------------------------------------------------------------------
1768
// Faster, more efficient version.
1769
// Copies subimage straight to dest texture
1770
void gld_TexSubImage2D_DX8( GLcontext *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 )
1779
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1780
GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx);
1782
IDirect3DTexture8 *pTex;
1783
IDirect3DSurface8 *pSurface;
1786
D3DLOCKED_RECT d3dLockedRect;
1787
D3DSURFACE_DESC d3dsd;
1789
if (!tObj || !texImage)
1792
pTex = (IDirect3DTexture8*)tObj->DriverData;
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);
1799
return; // Surface level doesn't exist (or just a plain error)
1801
IDirect3DSurface8_GetDesc(pSurface, &d3dsd);
1803
// Dest rectangle must be offset to dest image
1804
SetRect(&rcDstRect, 0, 0, width, height);
1805
OffsetRect(&rcDstRect, xoffset, yoffset);
1807
// Lock sub-rect of surface
1808
hr = IDirect3DSurface8_LockRect(pSurface, &d3dLockedRect, &rcDstRect, 0);
1810
IDirect3DSurface8_Release(pSurface);
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,
1819
0, 0, 0, // NOTE: d3dLockedRect.pBits is already offset!!!
1820
d3dLockedRect.Pitch,
1821
0, // dstImageStride
1822
format, type, pixels, packing);
1825
IDirect3DSurface8_UnlockRect(pSurface);
1826
IDirect3DSurface8_Release(pSurface);
1829
//---------------------------------------------------------------------------
1831
void gld_TexSubImage1D_DX8( GLcontext *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 )
1839
gld_TexSubImage2D_DX8(ctx, target, level, xoffset, 0, width, 1, format, type, pixels, packing, texObj, texImage);
1842
//---------------------------------------------------------------------------
1844
void gld_DeleteTexture_DX8(
1846
struct gl_texture_object *tObj)
1848
GLD_context *gld = (GLD_context*)(ctx->DriverCtx);
1851
IDirect3DTexture8 *pTex = (IDirect3DTexture8*)tObj->DriverData;
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;
1860
_GLD_DX8_TEX(Release(pTex));
1861
tObj->DriverData = NULL;
1866
//---------------------------------------------------------------------------
1868
__inline void _gldSetColorOps(
1869
const GLD_driver_dx8 *gld,
1872
D3DTEXTUREOP ColorOp,
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));
1880
//---------------------------------------------------------------------------
1882
__inline void _gldSetAlphaOps(
1883
const GLD_driver_dx8 *gld,
1886
D3DTEXTUREOP AlphaOp,
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));
1894
//---------------------------------------------------------------------------
1896
void gldUpdateTextureUnit(
1901
GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1902
GLD_driver_dx8 *gld = GLD_GET_DX8_DRIVER(gldCtx);
1904
D3DTEXTUREFILTERTYPE minfilter;
1905
D3DTEXTUREFILTERTYPE mipfilter;
1909
GLD_texenv *pTexenv;
1911
// NOTE: If bPassThrough is FALSE then texture stage can be
1912
// disabled otherwise it must pass-through it's current fragment.
1914
const struct gl_texture_unit *pUnit = &ctx->Texture.Unit[unit];
1915
const struct gl_texture_object *tObj = pUnit->_Current;
1917
IDirect3DTexture8 *pTex = NULL;
1919
pTex = (IDirect3DTexture8*)tObj->DriverData;
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))) {
1927
_GLD_DX8_DEV(SetTexture(gld->pDev, unit, pTex));
1929
// Disable texturing, then return
1930
_GLD_DX8_DEV(SetTexture(gld->pDev, unit, NULL));
1932
_gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE);
1933
_gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_SELECTARG2, D3DTA_DIFFUSE);
1935
_gldSetColorOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE);
1936
_gldSetAlphaOps(gld, unit, D3DTA_TEXTURE, D3DTOP_DISABLE, D3DTA_DIFFUSE);
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)));
1950
_GLD_DX8_TEX(SetPriority(pTex, (DWORD)(tObj->Priority*65535.0f)));
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);
1957
switch (BaseFormat) {
1969
switch (pUnit->EnvMode) {
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));
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);
1994
//---------------------------------------------------------------------------
1996
void gld_NEW_TEXTURE_DX8(
1999
// TODO: Support for three (ATI Radeon) or more (nVidia GeForce3) texture units
2005
return; // Sanity check
2007
if (ctx->Const.MaxTextureUnits == 1) {
2008
gldUpdateTextureUnit(ctx, 0, TRUE);
2013
// NOTE: THE FOLLOWING RELATES TO TWO TEXTURE UNITS, AND TWO ONLY!!
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;
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);
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);
2035
_GLD_DX8_DEV(ValidateDevice(gld->pDev, &dwPasses));
2036
// if (FAILED(hr)) {
2037
// gldLogError(GLDLOG_ERROR, "ValidateDevice failed", hr);
2039
if (dwPasses != 1) {
2040
gldLogMessage(GLDLOG_ERROR, "ValidateDevice: Can't do in one pass\n");
2046
//---------------------------------------------------------------------------