- some cleanups
[wine/wine-gecko.git] / dlls / d3d8 / utils.c
blob75ac1a5045eb1fca73c13b29a3dcfb86a98b457b
1 /*
2 * D3D8 utils
4 * Copyright 2002-2003 Jason Edmeades
5 * Raphael Junqueira
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
24 #include <math.h>
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "wingdi.h"
32 #include "wine/debug.h"
34 #include "d3d8_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
39 #if 0
40 # define VTRACE(A) TRACE A
41 #else
42 # define VTRACE(A)
43 #endif
45 const char* debug_d3ddevicetype(D3DDEVTYPE devtype) {
46 switch (devtype) {
47 #define DEVTYPE_TO_STR(dev) case dev: return #dev
48 DEVTYPE_TO_STR(D3DDEVTYPE_HAL);
49 DEVTYPE_TO_STR(D3DDEVTYPE_REF);
50 DEVTYPE_TO_STR(D3DDEVTYPE_SW);
51 #undef DEVTYPE_TO_STR
52 default:
53 FIXME("Unrecognized %u D3DDEVTYPE!\n", devtype);
54 return "unrecognized";
58 const char* debug_d3dusage(DWORD usage) {
59 switch (usage) {
60 #define D3DUSAGE_TO_STR(u) case u: return #u
61 D3DUSAGE_TO_STR(D3DUSAGE_RENDERTARGET);
62 D3DUSAGE_TO_STR(D3DUSAGE_DEPTHSTENCIL);
63 D3DUSAGE_TO_STR(D3DUSAGE_WRITEONLY);
64 D3DUSAGE_TO_STR(D3DUSAGE_SOFTWAREPROCESSING);
65 D3DUSAGE_TO_STR(D3DUSAGE_DONOTCLIP);
66 D3DUSAGE_TO_STR(D3DUSAGE_POINTS);
67 D3DUSAGE_TO_STR(D3DUSAGE_RTPATCHES);
68 D3DUSAGE_TO_STR(D3DUSAGE_NPATCHES);
69 D3DUSAGE_TO_STR(D3DUSAGE_DYNAMIC);
70 #undef D3DUSAGE_TO_STR
71 case 0: return "none";
72 default:
73 FIXME("Unrecognized %lu Usage!\n", usage);
74 return "unrecognized";
78 const char* debug_d3dformat(D3DFORMAT fmt) {
79 switch (fmt) {
80 #define FMT_TO_STR(fmt) case fmt: return #fmt
81 FMT_TO_STR(D3DFMT_UNKNOWN);
82 FMT_TO_STR(D3DFMT_R8G8B8);
83 FMT_TO_STR(D3DFMT_A8R8G8B8);
84 FMT_TO_STR(D3DFMT_X8R8G8B8);
85 FMT_TO_STR(D3DFMT_R5G6B5);
86 FMT_TO_STR(D3DFMT_X1R5G5B5);
87 FMT_TO_STR(D3DFMT_A1R5G5B5);
88 FMT_TO_STR(D3DFMT_A4R4G4B4);
89 FMT_TO_STR(D3DFMT_R3G3B2);
90 FMT_TO_STR(D3DFMT_A8);
91 FMT_TO_STR(D3DFMT_A8R3G3B2);
92 FMT_TO_STR(D3DFMT_X4R4G4B4);
93 FMT_TO_STR(D3DFMT_A8P8);
94 FMT_TO_STR(D3DFMT_P8);
95 FMT_TO_STR(D3DFMT_L8);
96 FMT_TO_STR(D3DFMT_A8L8);
97 FMT_TO_STR(D3DFMT_A4L4);
98 FMT_TO_STR(D3DFMT_V8U8);
99 FMT_TO_STR(D3DFMT_L6V5U5);
100 FMT_TO_STR(D3DFMT_X8L8V8U8);
101 FMT_TO_STR(D3DFMT_Q8W8V8U8);
102 FMT_TO_STR(D3DFMT_V16U16);
103 FMT_TO_STR(D3DFMT_W11V11U10);
104 FMT_TO_STR(D3DFMT_UYVY);
105 FMT_TO_STR(D3DFMT_YUY2);
106 FMT_TO_STR(D3DFMT_DXT1);
107 FMT_TO_STR(D3DFMT_DXT2);
108 FMT_TO_STR(D3DFMT_DXT3);
109 FMT_TO_STR(D3DFMT_DXT4);
110 FMT_TO_STR(D3DFMT_DXT5);
111 FMT_TO_STR(D3DFMT_D16_LOCKABLE);
112 FMT_TO_STR(D3DFMT_D32);
113 FMT_TO_STR(D3DFMT_D15S1);
114 FMT_TO_STR(D3DFMT_D24S8);
115 FMT_TO_STR(D3DFMT_D16);
116 FMT_TO_STR(D3DFMT_D24X8);
117 FMT_TO_STR(D3DFMT_D24X4S4);
118 FMT_TO_STR(D3DFMT_VERTEXDATA);
119 FMT_TO_STR(D3DFMT_INDEX16);
120 FMT_TO_STR(D3DFMT_INDEX32);
121 #undef FMT_TO_STR
122 default:
123 FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
124 return "unrecognized";
128 const char* debug_d3dressourcetype(D3DRESOURCETYPE res) {
129 switch (res) {
130 #define RES_TO_STR(res) case res: return #res;
131 RES_TO_STR(D3DRTYPE_SURFACE);
132 RES_TO_STR(D3DRTYPE_VOLUME);
133 RES_TO_STR(D3DRTYPE_TEXTURE);
134 RES_TO_STR(D3DRTYPE_VOLUMETEXTURE);
135 RES_TO_STR(D3DRTYPE_CUBETEXTURE);
136 RES_TO_STR(D3DRTYPE_VERTEXBUFFER);
137 RES_TO_STR(D3DRTYPE_INDEXBUFFER);
138 #undef RES_TO_STR
139 default:
140 FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res);
141 return "unrecognized";
145 const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) {
146 switch (PrimitiveType) {
147 #define PRIM_TO_STR(prim) case prim: return #prim;
148 PRIM_TO_STR(D3DPT_POINTLIST);
149 PRIM_TO_STR(D3DPT_LINELIST);
150 PRIM_TO_STR(D3DPT_LINESTRIP);
151 PRIM_TO_STR(D3DPT_TRIANGLELIST);
152 PRIM_TO_STR(D3DPT_TRIANGLESTRIP);
153 PRIM_TO_STR(D3DPT_TRIANGLEFAN);
154 #undef PRIM_TO_STR
155 default:
156 FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
157 return "unrecognized";
161 const char* debug_d3dpool(D3DPOOL Pool) {
162 switch (Pool) {
163 #define POOL_TO_STR(p) case p: return #p;
164 POOL_TO_STR(D3DPOOL_DEFAULT);
165 POOL_TO_STR(D3DPOOL_MANAGED);
166 POOL_TO_STR(D3DPOOL_SYSTEMMEM);
167 POOL_TO_STR(D3DPOOL_SCRATCH);
168 #undef POOL_TO_STR
169 default:
170 FIXME("Unrecognized %u D3DPOOL!\n", Pool);
171 return "unrecognized";
176 * Simple utility routines used for dx -> gl mapping of byte formats
178 int D3DPrimitiveListGetVertexSize(D3DPRIMITIVETYPE PrimitiveType, int iNumPrim) {
179 switch (PrimitiveType) {
180 case D3DPT_POINTLIST: return iNumPrim;
181 case D3DPT_LINELIST: return iNumPrim * 2;
182 case D3DPT_LINESTRIP: return iNumPrim + 1;
183 case D3DPT_TRIANGLELIST: return iNumPrim * 3;
184 case D3DPT_TRIANGLESTRIP: return iNumPrim + 2;
185 case D3DPT_TRIANGLEFAN: return iNumPrim + 2;
186 default:
187 FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
188 return 0;
192 int D3DPrimitive2GLenum(D3DPRIMITIVETYPE PrimitiveType) {
193 switch (PrimitiveType) {
194 case D3DPT_POINTLIST: return GL_POINTS;
195 case D3DPT_LINELIST: return GL_LINES;
196 case D3DPT_LINESTRIP: return GL_LINE_STRIP;
197 case D3DPT_TRIANGLELIST: return GL_TRIANGLES;
198 case D3DPT_TRIANGLESTRIP: return GL_TRIANGLE_STRIP;
199 case D3DPT_TRIANGLEFAN: return GL_TRIANGLE_FAN;
200 default:
201 FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", PrimitiveType);
202 return GL_POLYGON;
206 int D3DFVFGetSize(D3DFORMAT fvf) {
207 int ret = 0;
208 if (fvf & D3DFVF_XYZ) ret += 3 * sizeof(float);
209 else if (fvf & D3DFVF_XYZRHW) ret += 4 * sizeof(float);
210 if (fvf & D3DFVF_NORMAL) ret += 3 * sizeof(float);
211 if (fvf & D3DFVF_PSIZE) ret += sizeof(float);
212 if (fvf & D3DFVF_DIFFUSE) ret += sizeof(DWORD);
213 if (fvf & D3DFVF_SPECULAR) ret += sizeof(DWORD);
214 /*if (fvf & D3DFVF_TEX1) ret += 1;*/
215 return ret;
218 GLenum D3DFmt2GLDepthFmt(D3DFORMAT fmt) {
219 switch (fmt) {
220 /* depth/stencil buffer */
221 case D3DFMT_D16_LOCKABLE:
222 case D3DFMT_D16:
223 case D3DFMT_D15S1:
224 case D3DFMT_D24X4S4:
225 case D3DFMT_D24S8:
226 case D3DFMT_D24X8:
227 case D3DFMT_D32:
228 return GL_DEPTH_COMPONENT;
229 default:
230 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
232 return 0;
235 GLenum D3DFmt2GLDepthType(D3DFORMAT fmt) {
236 switch (fmt) {
237 /* depth/stencil buffer */
238 case D3DFMT_D15S1:
239 case D3DFMT_D16_LOCKABLE:
240 case D3DFMT_D16:
241 return GL_UNSIGNED_SHORT;
242 case D3DFMT_D24X4S4:
243 case D3DFMT_D24S8:
244 case D3DFMT_D24X8:
245 case D3DFMT_D32:
246 return GL_UNSIGNED_INT;
247 default:
248 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
250 return 0;
253 SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
254 SHORT retVal;
256 switch (fmt) {
257 /* color buffer */
258 case D3DFMT_P8: retVal = 1; break;
259 case D3DFMT_R3G3B2: retVal = 1; break;
260 case D3DFMT_R5G6B5: retVal = 2; break;
261 case D3DFMT_X1R5G5B5: retVal = 2; break;
262 case D3DFMT_A4R4G4B4: retVal = 2; break;
263 case D3DFMT_X4R4G4B4: retVal = 2; break;
264 case D3DFMT_A1R5G5B5: retVal = 2; break;
265 case D3DFMT_R8G8B8: retVal = 3; break;
266 case D3DFMT_X8R8G8B8: retVal = 4; break;
267 case D3DFMT_A8R8G8B8: retVal = 4; break;
268 /* depth/stencil buffer */
269 case D3DFMT_D16_LOCKABLE: retVal = 2; break;
270 case D3DFMT_D16: retVal = 2; break;
271 case D3DFMT_D15S1: retVal = 2; break;
272 case D3DFMT_D24X4S4: retVal = 4; break;
273 case D3DFMT_D24S8: retVal = 4; break;
274 case D3DFMT_D24X8: retVal = 4; break;
275 case D3DFMT_D32: retVal = 4; break;
276 /* unknown */
277 case D3DFMT_UNKNOWN:
278 /* Guess at the highest value of the above */
279 TRACE("D3DFMT_UNKNOWN - Guessing at 4 bytes/pixel %u\n", fmt);
280 retVal = 4;
281 break;
283 default:
284 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
285 retVal = 4;
287 TRACE("bytes/Pxl for fmt(%u,%s) = %d\n", fmt, debug_d3dformat(fmt), retVal);
288 return retVal;
291 GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
292 GLint retVal;
294 switch (fmt) {
295 case D3DFMT_P8: retVal = GL_COLOR_INDEX8_EXT; break;
296 case D3DFMT_A8P8: retVal = GL_COLOR_INDEX8_EXT; break;
298 case D3DFMT_A4R4G4B4: retVal = GL_RGBA4; break;
299 case D3DFMT_A8R8G8B8: retVal = GL_RGBA8; break;
300 case D3DFMT_X8R8G8B8: retVal = GL_RGB8; break;
301 case D3DFMT_R8G8B8: retVal = GL_RGB8; break;
302 case D3DFMT_R5G6B5: retVal = GL_RGB5; break; /* fixme: internal format 6 for g? */
303 case D3DFMT_A1R5G5B5: retVal = GL_RGB5_A1; break;
304 default:
305 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
306 retVal = GL_RGB8;
308 #if defined(GL_EXT_texture_compression_s3tc)
309 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
310 switch (fmt) {
311 case D3DFMT_DXT1: retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
312 case D3DFMT_DXT3: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
313 case D3DFMT_DXT5: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
314 default:
315 /* stupid compiler */
316 break;
319 #endif
320 TRACE("fmt2glintFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
321 return retVal;
324 GLenum D3DFmt2GLFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
325 GLenum retVal;
327 switch (fmt) {
328 case D3DFMT_P8: retVal = GL_COLOR_INDEX; break;
329 case D3DFMT_A8P8: retVal = GL_COLOR_INDEX; break;
331 case D3DFMT_A4R4G4B4: retVal = GL_BGRA; break;
332 case D3DFMT_A8R8G8B8: retVal = GL_BGRA; break;
333 case D3DFMT_X8R8G8B8: retVal = GL_BGRA; break;
334 case D3DFMT_R8G8B8: retVal = GL_BGR; break;
335 case D3DFMT_R5G6B5: retVal = GL_RGB; break;
336 case D3DFMT_A1R5G5B5: retVal = GL_BGRA; break;
337 default:
338 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
339 retVal = GL_BGR;
341 #if defined(GL_EXT_texture_compression_s3tc)
342 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
343 switch (fmt) {
344 case D3DFMT_DXT1: retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
345 case D3DFMT_DXT3: retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
346 case D3DFMT_DXT5: retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
347 default:
348 /* stupid compiler */
349 break;
352 #endif
353 TRACE("fmt2glFmt for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
354 return retVal;
357 GLenum D3DFmt2GLType(IDirect3DDevice8Impl* This, D3DFORMAT fmt) {
358 GLenum retVal;
360 switch (fmt) {
361 case D3DFMT_P8: retVal = GL_UNSIGNED_BYTE; break;
362 case D3DFMT_A8P8: retVal = GL_UNSIGNED_BYTE; break;
364 case D3DFMT_A4R4G4B4: retVal = GL_UNSIGNED_SHORT_4_4_4_4_REV; break;
365 case D3DFMT_A8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
366 case D3DFMT_X8R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
367 case D3DFMT_R5G6B5: retVal = GL_UNSIGNED_SHORT_5_6_5; break;
368 case D3DFMT_R8G8B8: retVal = GL_UNSIGNED_BYTE; break;
369 case D3DFMT_A1R5G5B5: retVal = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
370 default:
371 FIXME("Unhandled fmt(%u,%s)\n", fmt, debug_d3dformat(fmt));
372 retVal = GL_UNSIGNED_BYTE;
374 #if defined(GL_EXT_texture_compression_s3tc)
375 if (GL_SUPPORT(EXT_TEXTURE_COMPRESSION_S3TC)) {
376 switch (fmt) {
377 case D3DFMT_DXT1: retVal = 0; break;
378 case D3DFMT_DXT3: retVal = 0; break;
379 case D3DFMT_DXT5: retVal = 0; break;
380 default:
381 /* stupid compiler */
382 break;
385 #endif
386 TRACE("fmt2glType for fmt(%u,%s) = %x\n", fmt, debug_d3dformat(fmt), retVal);
387 return retVal;
390 int SOURCEx_RGB_EXT(DWORD arg) {
391 switch(arg) {
392 case D3DTSS_COLORARG0: return GL_SOURCE2_RGB_EXT;
393 case D3DTSS_COLORARG1: return GL_SOURCE0_RGB_EXT;
394 case D3DTSS_COLORARG2: return GL_SOURCE1_RGB_EXT;
395 case D3DTSS_ALPHAARG0:
396 case D3DTSS_ALPHAARG1:
397 case D3DTSS_ALPHAARG2:
398 default:
399 FIXME("Invalid arg %ld\n", arg);
400 return GL_SOURCE0_RGB_EXT;
404 int OPERANDx_RGB_EXT(DWORD arg) {
405 switch(arg) {
406 case D3DTSS_COLORARG0: return GL_OPERAND2_RGB_EXT;
407 case D3DTSS_COLORARG1: return GL_OPERAND0_RGB_EXT;
408 case D3DTSS_COLORARG2: return GL_OPERAND1_RGB_EXT;
409 case D3DTSS_ALPHAARG0:
410 case D3DTSS_ALPHAARG1:
411 case D3DTSS_ALPHAARG2:
412 default:
413 FIXME("Invalid arg %ld\n", arg);
414 return GL_OPERAND0_RGB_EXT;
418 int SOURCEx_ALPHA_EXT(DWORD arg) {
419 switch(arg) {
420 case D3DTSS_ALPHAARG0: return GL_SOURCE2_ALPHA_EXT;
421 case D3DTSS_ALPHAARG1: return GL_SOURCE0_ALPHA_EXT;
422 case D3DTSS_ALPHAARG2: return GL_SOURCE1_ALPHA_EXT;
423 case D3DTSS_COLORARG0:
424 case D3DTSS_COLORARG1:
425 case D3DTSS_COLORARG2:
426 default:
427 FIXME("Invalid arg %ld\n", arg);
428 return GL_SOURCE0_ALPHA_EXT;
432 int OPERANDx_ALPHA_EXT(DWORD arg) {
433 switch(arg) {
434 case D3DTSS_ALPHAARG0: return GL_OPERAND2_ALPHA_EXT;
435 case D3DTSS_ALPHAARG1: return GL_OPERAND0_ALPHA_EXT;
436 case D3DTSS_ALPHAARG2: return GL_OPERAND1_ALPHA_EXT;
437 case D3DTSS_COLORARG0:
438 case D3DTSS_COLORARG1:
439 case D3DTSS_COLORARG2:
440 default:
441 FIXME("Invalid arg %ld\n", arg);
442 return GL_OPERAND0_ALPHA_EXT;
446 GLenum StencilOp(DWORD op) {
447 switch(op) {
448 case D3DSTENCILOP_KEEP : return GL_KEEP;
449 case D3DSTENCILOP_ZERO : return GL_ZERO;
450 case D3DSTENCILOP_REPLACE : return GL_REPLACE;
451 case D3DSTENCILOP_INCRSAT : return GL_INCR;
452 case D3DSTENCILOP_DECRSAT : return GL_DECR;
453 case D3DSTENCILOP_INVERT : return GL_INVERT;
454 #if defined(GL_VERSION_1_4)
455 case D3DSTENCILOP_INCR : return GL_INCR_WRAP;
456 case D3DSTENCILOP_DECR : return GL_DECR_WRAP;
457 #elif defined(GL_EXT_stencil_wrap)
458 case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
459 case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
460 #else
461 case D3DSTENCILOP_INCR : FIXME("Unsupported stencil op D3DSTENCILOP_INCR\n");
462 return GL_INCR; /* Fixme - needs to support wrap */
463 case D3DSTENCILOP_DECR : FIXME("Unsupported stencil op D3DSTENCILOP_DECR\n");
464 return GL_DECR; /* Fixme - needs to support wrap */
465 #endif
466 default:
467 FIXME("Invalid stencil op %ld\n", op);
468 return GL_ALWAYS;