blob: a57302589fc165733bd737ed0dc7b0dc046292bb [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// utilities.cpp: Conversion functions and other utility routines.
8
daniel@transgaming.combbf56f72010-04-20 18:52:13 +00009#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000010
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +000011#include <limits>
12
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000013#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000014
15#include "libGLESv2/mathutil.h"
16#include "libGLESv2/Context.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000017
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000018namespace gl
19{
20
21int UniformComponentCount(GLenum type)
22{
23 switch (type)
24 {
25 case GL_BOOL:
26 case GL_FLOAT:
27 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000028 case GL_SAMPLER_2D:
29 case GL_SAMPLER_CUBE:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000030 return 1;
31 case GL_BOOL_VEC2:
32 case GL_FLOAT_VEC2:
33 case GL_INT_VEC2:
34 return 2;
35 case GL_INT_VEC3:
36 case GL_FLOAT_VEC3:
37 case GL_BOOL_VEC3:
38 return 3;
39 case GL_BOOL_VEC4:
40 case GL_FLOAT_VEC4:
41 case GL_INT_VEC4:
42 case GL_FLOAT_MAT2:
43 return 4;
44 case GL_FLOAT_MAT3:
45 return 9;
46 case GL_FLOAT_MAT4:
47 return 16;
48 default:
49 UNREACHABLE();
50 }
51
52 return 0;
53}
54
55GLenum UniformComponentType(GLenum type)
56{
57 switch(type)
58 {
59 case GL_BOOL:
60 case GL_BOOL_VEC2:
61 case GL_BOOL_VEC3:
62 case GL_BOOL_VEC4:
63 return GL_BOOL;
64 case GL_FLOAT:
65 case GL_FLOAT_VEC2:
66 case GL_FLOAT_VEC3:
67 case GL_FLOAT_VEC4:
68 case GL_FLOAT_MAT2:
69 case GL_FLOAT_MAT3:
70 case GL_FLOAT_MAT4:
71 return GL_FLOAT;
72 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000073 case GL_SAMPLER_2D:
74 case GL_SAMPLER_CUBE:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000075 case GL_INT_VEC2:
76 case GL_INT_VEC3:
77 case GL_INT_VEC4:
78 return GL_INT;
79 default:
80 UNREACHABLE();
81 }
82
83 return GL_NONE;
84}
85
86size_t UniformTypeSize(GLenum type)
87{
88 switch(type)
89 {
90 case GL_BOOL: return sizeof(GLboolean);
91 case GL_FLOAT: return sizeof(GLfloat);
92 case GL_INT: return sizeof(GLint);
93 }
94
95 return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
96}
97
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +000098int VariableRowCount(GLenum type)
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +000099{
100 switch (type)
101 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000102 case GL_NONE:
103 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000104 case GL_BOOL:
105 case GL_FLOAT:
106 case GL_INT:
107 case GL_BOOL_VEC2:
108 case GL_FLOAT_VEC2:
109 case GL_INT_VEC2:
110 case GL_INT_VEC3:
111 case GL_FLOAT_VEC3:
112 case GL_BOOL_VEC3:
113 case GL_BOOL_VEC4:
114 case GL_FLOAT_VEC4:
115 case GL_INT_VEC4:
116 return 1;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000117 case GL_FLOAT_MAT2:
118 return 2;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000119 case GL_FLOAT_MAT3:
120 return 3;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000121 case GL_FLOAT_MAT4:
122 return 4;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000123 default:
124 UNREACHABLE();
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000125 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000126
127 return 0;
128}
129
130int VariableColumnCount(GLenum type)
131{
132 switch (type)
133 {
134 case GL_NONE:
135 return 0;
136 case GL_BOOL:
137 case GL_FLOAT:
138 case GL_INT:
139 return 1;
140 case GL_BOOL_VEC2:
141 case GL_FLOAT_VEC2:
142 case GL_INT_VEC2:
143 case GL_FLOAT_MAT2:
144 return 2;
145 case GL_INT_VEC3:
146 case GL_FLOAT_VEC3:
147 case GL_BOOL_VEC3:
148 case GL_FLOAT_MAT3:
149 return 3;
150 case GL_BOOL_VEC4:
151 case GL_FLOAT_VEC4:
152 case GL_INT_VEC4:
153 case GL_FLOAT_MAT4:
154 return 4;
155 default:
156 UNREACHABLE();
157 }
158
159 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000160}
161
162int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
163{
164 ASSERT(allocationSize <= bitsSize);
165
166 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
167
168 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
169 {
170 if ((*bits & mask) == 0)
171 {
172 *bits |= mask;
173 return i;
174 }
175
176 mask <<= 1;
177 }
178
179 return -1;
180}
181
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000182GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
183{
184 ASSERT(alignment > 0 && isPow2(alignment));
185
186 GLsizei rawPitch = ComputePixelSize(format, type) * width;
187 return (rawPitch + alignment - 1) & ~(alignment - 1);
188}
189
daniel@transgaming.com01868132010-08-24 19:21:17 +0000190GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
191{
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +0000192 return ComputeCompressedSize(width, 1, format);
daniel@transgaming.com01868132010-08-24 19:21:17 +0000193}
194
195GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
196{
197 switch (format)
198 {
199 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
200 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
201 break;
202 default:
203 return 0;
204 }
205
206 return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
207}
208
209bool IsCompressed(GLenum format)
210{
211 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
212 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
213 {
214 return true;
215 }
216 else
217 {
218 return false;
219 }
220}
221
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000222// Returns the size, in bytes, of a single texel in an Image
223int ComputePixelSize(GLenum format, GLenum type)
224{
225 switch (type)
226 {
227 case GL_UNSIGNED_BYTE:
228 switch (format)
229 {
230 case GL_ALPHA: return sizeof(unsigned char);
231 case GL_LUMINANCE: return sizeof(unsigned char);
232 case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
233 case GL_RGB: return sizeof(unsigned char) * 3;
234 case GL_RGBA: return sizeof(unsigned char) * 4;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000235 case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000236 default: UNREACHABLE();
237 }
238 break;
239 case GL_UNSIGNED_SHORT_4_4_4_4:
240 case GL_UNSIGNED_SHORT_5_5_5_1:
241 case GL_UNSIGNED_SHORT_5_6_5:
242 return sizeof(unsigned short);
daniel@transgaming.com0a337e92010-08-28 17:38:27 +0000243 case GL_FLOAT:
244 switch (format)
245 {
246 case GL_ALPHA: return sizeof(float);
247 case GL_LUMINANCE: return sizeof(float);
248 case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
249 case GL_RGB: return sizeof(float) * 3;
250 case GL_RGBA: return sizeof(float) * 4;
251 default: UNREACHABLE();
252 }
253 break;
254 case GL_HALF_FLOAT_OES:
255 switch (format)
256 {
257 case GL_ALPHA: return sizeof(unsigned short);
258 case GL_LUMINANCE: return sizeof(unsigned short);
259 case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
260 case GL_RGB: return sizeof(unsigned short) * 3;
261 case GL_RGBA: return sizeof(unsigned short) * 4;
262 default: UNREACHABLE();
263 }
264 break;
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000265 default: UNREACHABLE();
266 }
267
268 return 0;
269}
270
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000271bool IsCubemapTextureTarget(GLenum target)
272{
273 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
274}
275
276bool IsTextureTarget(GLenum target)
277{
278 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
279}
280
281// Verify that format/type are one of the combinations from table 3.4.
282bool CheckTextureFormatType(GLenum format, GLenum type)
283{
284 switch (type)
285 {
286 case GL_UNSIGNED_BYTE:
287 switch (format)
288 {
289 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000290 case GL_BGRA_EXT:
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000291 case GL_RGB:
292 case GL_ALPHA:
293 case GL_LUMINANCE:
294 case GL_LUMINANCE_ALPHA:
295 return true;
296
297 default:
298 return false;
299 }
300
daniel@transgaming.com0a337e92010-08-28 17:38:27 +0000301 case GL_FLOAT:
302 case GL_HALF_FLOAT_OES:
303 switch (format)
304 {
305 case GL_RGBA:
306 case GL_RGB:
307 case GL_ALPHA:
308 case GL_LUMINANCE:
309 case GL_LUMINANCE_ALPHA:
310 return true;
311
312 default:
313 return false;
314 }
315
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000316 case GL_UNSIGNED_SHORT_4_4_4_4:
317 case GL_UNSIGNED_SHORT_5_5_5_1:
318 return (format == GL_RGBA);
319
320 case GL_UNSIGNED_SHORT_5_6_5:
321 return (format == GL_RGB);
322
323 default:
324 return false;
325 }
326}
327
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000328bool IsColorRenderable(GLenum internalformat)
329{
330 switch (internalformat)
331 {
332 case GL_RGBA4:
333 case GL_RGB5_A1:
334 case GL_RGB565:
335 case GL_RGB8_OES:
336 case GL_RGBA8_OES:
337 return true;
338 case GL_DEPTH_COMPONENT16:
339 case GL_STENCIL_INDEX8:
340 case GL_DEPTH24_STENCIL8_OES:
341 return false;
342 default:
343 UNIMPLEMENTED();
344 }
345
346 return false;
347}
348
349bool IsDepthRenderable(GLenum internalformat)
350{
351 switch (internalformat)
352 {
353 case GL_DEPTH_COMPONENT16:
354 case GL_DEPTH24_STENCIL8_OES:
355 return true;
356 case GL_STENCIL_INDEX8:
357 case GL_RGBA4:
358 case GL_RGB5_A1:
359 case GL_RGB565:
360 case GL_RGB8_OES:
361 case GL_RGBA8_OES:
362 return false;
363 default:
364 UNIMPLEMENTED();
365 }
366
367 return false;
368}
369
370bool IsStencilRenderable(GLenum internalformat)
371{
372 switch (internalformat)
373 {
374 case GL_STENCIL_INDEX8:
375 case GL_DEPTH24_STENCIL8_OES:
376 return true;
377 case GL_RGBA4:
378 case GL_RGB5_A1:
379 case GL_RGB565:
380 case GL_RGB8_OES:
381 case GL_RGBA8_OES:
382 case GL_DEPTH_COMPONENT16:
383 return false;
384 default:
385 UNIMPLEMENTED();
386 }
387
388 return false;
389}
390
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000391}
392
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000393namespace es2dx
394{
395
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000396D3DCMPFUNC ConvertComparison(GLenum comparison)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000397{
398 D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
399 switch (comparison)
400 {
401 case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
402 case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
403 case GL_LESS: d3dComp = D3DCMP_LESS; break;
404 case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
405 case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
406 case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
407 case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
408 case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
409 default: UNREACHABLE();
410 }
411
412 return d3dComp;
413}
414
415D3DCOLOR ConvertColor(gl::Color color)
416{
417 return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000418 gl::unorm<8>(color.green),
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000419 gl::unorm<8>(color.blue),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000420 gl::unorm<8>(color.alpha));
421}
422
423D3DBLEND ConvertBlendFunc(GLenum blend)
424{
425 D3DBLEND d3dBlend = D3DBLEND_ZERO;
426
427 switch (blend)
428 {
429 case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
430 case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
431 case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
432 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
433 case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
434 case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
435 case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
436 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
437 case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
438 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
439 case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
440 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
441 case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
442 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
443 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
444 default: UNREACHABLE();
445 }
446
447 return d3dBlend;
448}
449
450D3DBLENDOP ConvertBlendOp(GLenum blendOp)
451{
452 D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
453
454 switch (blendOp)
455 {
456 case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
457 case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
458 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
459 default: UNREACHABLE();
460 }
461
462 return d3dBlendOp;
463}
464
465D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
466{
467 D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
468
469 switch (stencilOp)
470 {
471 case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
472 case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
473 case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
474 case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
475 case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
476 case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
477 case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
478 case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
479 default: UNREACHABLE();
480 }
481
482 return d3dStencilOp;
483}
484
485D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
486{
487 D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
488
489 switch (wrap)
490 {
491 case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
492 case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
493 case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
494 default: UNREACHABLE();
495 }
496
497 return d3dWrap;
498}
499
500D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
501{
502 D3DCULL cull = D3DCULL_CCW;
503 switch (cullFace)
504 {
505 case GL_FRONT:
506 cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
507 break;
508 case GL_BACK:
509 cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
510 break;
511 case GL_FRONT_AND_BACK:
daniel@transgaming.comace5e662010-03-21 04:31:20 +0000512 cull = D3DCULL_NONE; // culling will be handled during draw
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513 break;
514 default: UNREACHABLE();
515 }
516
517 return cull;
518}
519
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +0000520D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
521{
522 D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
523
524 // Map a cube map texture target to the corresponding D3D surface index. Note that the
525 // Y faces are swapped because the Y coordinate to the texture lookup intrinsic functions
526 // are negated in the pixel shader.
527 switch (cubeFace)
528 {
529 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
530 face = D3DCUBEMAP_FACE_POSITIVE_X;
531 break;
532 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
533 face = D3DCUBEMAP_FACE_NEGATIVE_X;
534 break;
535 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
536 face = D3DCUBEMAP_FACE_NEGATIVE_Y;
537 break;
538 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
539 face = D3DCUBEMAP_FACE_POSITIVE_Y;
540 break;
541 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
542 face = D3DCUBEMAP_FACE_POSITIVE_Z;
543 break;
544 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
545 face = D3DCUBEMAP_FACE_NEGATIVE_Z;
546 break;
547 default: UNREACHABLE();
548 }
549
550 return face;
551}
552
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000553DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
554{
555 return (red ? D3DCOLORWRITEENABLE_RED : 0) |
556 (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
557 (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
558 (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
559}
560
561D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
562{
563 D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
564 switch (magFilter)
565 {
566 case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
567 case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
568 default: UNREACHABLE();
569 }
570
571 return d3dMagFilter;
572}
573
574void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
575{
576 switch (minFilter)
577 {
578 case GL_NEAREST:
579 *d3dMinFilter = D3DTEXF_POINT;
580 *d3dMipFilter = D3DTEXF_NONE;
581 break;
582 case GL_LINEAR:
583 *d3dMinFilter = D3DTEXF_LINEAR;
584 *d3dMipFilter = D3DTEXF_NONE;
585 break;
586 case GL_NEAREST_MIPMAP_NEAREST:
587 *d3dMinFilter = D3DTEXF_POINT;
588 *d3dMipFilter = D3DTEXF_POINT;
589 break;
590 case GL_LINEAR_MIPMAP_NEAREST:
591 *d3dMinFilter = D3DTEXF_LINEAR;
592 *d3dMipFilter = D3DTEXF_POINT;
593 break;
594 case GL_NEAREST_MIPMAP_LINEAR:
595 *d3dMinFilter = D3DTEXF_POINT;
596 *d3dMipFilter = D3DTEXF_LINEAR;
597 break;
598 case GL_LINEAR_MIPMAP_LINEAR:
599 *d3dMinFilter = D3DTEXF_LINEAR;
600 *d3dMipFilter = D3DTEXF_LINEAR;
601 break;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000602 default:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000603 *d3dMinFilter = D3DTEXF_POINT;
604 *d3dMipFilter = D3DTEXF_NONE;
605 UNREACHABLE();
606 }
607}
608
609unsigned int GetStencilSize(D3DFORMAT stencilFormat)
610{
611 switch(stencilFormat)
612 {
613 case D3DFMT_D24FS8:
614 case D3DFMT_D24S8:
615 return 8;
616 case D3DFMT_D24X4S4:
617 return 4;
618 case D3DFMT_D15S1:
619 return 1;
620 case D3DFMT_D16_LOCKABLE:
621 case D3DFMT_D32:
622 case D3DFMT_D24X8:
623 case D3DFMT_D32F_LOCKABLE:
624 case D3DFMT_D16:
625 return 0;
626// case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
627// case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
628 default: UNREACHABLE();
629 }
630 return 0;
631}
632
633unsigned int GetAlphaSize(D3DFORMAT colorFormat)
634{
635 switch (colorFormat)
636 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000637 case D3DFMT_A16B16G16R16F:
638 return 16;
639 case D3DFMT_A32B32G32R32F:
640 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000641 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000642 return 2;
643 case D3DFMT_A8R8G8B8:
644 return 8;
645 case D3DFMT_A1R5G5B5:
646 return 1;
647 case D3DFMT_X8R8G8B8:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000648 case D3DFMT_R5G6B5:
649 return 0;
650 default: UNREACHABLE();
651 }
652 return 0;
653}
654
655unsigned int GetRedSize(D3DFORMAT colorFormat)
656{
657 switch (colorFormat)
658 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000659 case D3DFMT_A16B16G16R16F:
660 return 16;
661 case D3DFMT_A32B32G32R32F:
662 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000663 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000664 return 10;
665 case D3DFMT_A8R8G8B8:
666 case D3DFMT_X8R8G8B8:
667 return 8;
668 case D3DFMT_A1R5G5B5:
669 case D3DFMT_R5G6B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000670 return 5;
671 default: UNREACHABLE();
672 }
673 return 0;
674}
675
676unsigned int GetGreenSize(D3DFORMAT colorFormat)
677{
678 switch (colorFormat)
679 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000680 case D3DFMT_A16B16G16R16F:
681 return 16;
682 case D3DFMT_A32B32G32R32F:
683 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000684 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000685 return 10;
686 case D3DFMT_A8R8G8B8:
687 case D3DFMT_X8R8G8B8:
688 return 8;
689 case D3DFMT_A1R5G5B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690 return 5;
691 case D3DFMT_R5G6B5:
692 return 6;
693 default: UNREACHABLE();
694 }
695 return 0;
696}
697
698unsigned int GetBlueSize(D3DFORMAT colorFormat)
699{
700 switch (colorFormat)
701 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000702 case D3DFMT_A16B16G16R16F:
703 return 16;
704 case D3DFMT_A32B32G32R32F:
705 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000706 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000707 return 10;
708 case D3DFMT_A8R8G8B8:
709 case D3DFMT_X8R8G8B8:
710 return 8;
711 case D3DFMT_A1R5G5B5:
712 case D3DFMT_R5G6B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713 return 5;
714 default: UNREACHABLE();
715 }
716 return 0;
717}
718
719unsigned int GetDepthSize(D3DFORMAT depthFormat)
720{
721 switch (depthFormat)
722 {
723 case D3DFMT_D16_LOCKABLE: return 16;
724 case D3DFMT_D32: return 32;
725 case D3DFMT_D15S1: return 15;
726 case D3DFMT_D24S8: return 24;
727 case D3DFMT_D24X8: return 24;
728 case D3DFMT_D24X4S4: return 24;
729 case D3DFMT_D16: return 16;
730 case D3DFMT_D32F_LOCKABLE: return 32;
731 case D3DFMT_D24FS8: return 24;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000732 //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
733 //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000734 default:
735 UNREACHABLE();
736 }
737 return 0;
738}
739
daniel@transgaming.com83921382011-01-08 05:46:00 +0000740bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000741 D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
742{
743 switch (primitiveType)
744 {
745 case GL_POINTS:
746 *d3dPrimitiveType = D3DPT_POINTLIST;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000747 *d3dPrimitiveCount = elementCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748 break;
749 case GL_LINES:
750 *d3dPrimitiveType = D3DPT_LINELIST;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000751 *d3dPrimitiveCount = elementCount / 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000752 break;
753 case GL_LINE_LOOP:
daniel@transgaming.combf2b52a2010-04-20 18:53:03 +0000754 *d3dPrimitiveType = D3DPT_LINESTRIP;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000755 *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000756 break;
757 case GL_LINE_STRIP:
758 *d3dPrimitiveType = D3DPT_LINESTRIP;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000759 *d3dPrimitiveCount = elementCount - 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000760 break;
761 case GL_TRIANGLES:
762 *d3dPrimitiveType = D3DPT_TRIANGLELIST;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000763 *d3dPrimitiveCount = elementCount / 3;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000764 break;
765 case GL_TRIANGLE_STRIP:
766 *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000767 *d3dPrimitiveCount = elementCount - 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000768 break;
769 case GL_TRIANGLE_FAN:
770 *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000771 *d3dPrimitiveCount = elementCount - 2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000772 break;
773 default:
774 return false;
775 }
776
777 return true;
778}
779
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000780D3DFORMAT ConvertRenderbufferFormat(GLenum format)
781{
782 switch (format)
783 {
784 case GL_RGBA4:
daniel@transgaming.com63977542010-08-24 19:21:02 +0000785 case GL_RGB5_A1:
786 case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000787 case GL_RGB565: return D3DFMT_R5G6B5;
daniel@transgaming.com63977542010-08-24 19:21:02 +0000788 case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000789 case GL_DEPTH_COMPONENT16:
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000790 case GL_STENCIL_INDEX8:
791 case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000792 default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
793 }
794}
795
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000796GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
797{
798 if (type == D3DMULTISAMPLE_NONMASKABLE)
799 return 0;
800 else
801 return type;
802}
803
804D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
805{
806 if (samples <= 1)
807 return D3DMULTISAMPLE_NONE;
808 else
809 return (D3DMULTISAMPLE_TYPE)samples;
810}
811
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000812}
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000813
814namespace dx2es
815{
816
817GLenum ConvertBackBufferFormat(D3DFORMAT format)
818{
819 switch (format)
820 {
821 case D3DFMT_A4R4G4B4: return GL_RGBA4;
822 case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
823 case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
824 case D3DFMT_R5G6B5: return GL_RGB565;
825 case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
826 default:
827 UNREACHABLE();
828 }
829
830 return GL_RGBA4;
831}
832
833GLenum ConvertDepthStencilFormat(D3DFORMAT format)
834{
835 switch (format)
836 {
837 case D3DFMT_D16:
838 case D3DFMT_D24X8:
839 return GL_DEPTH_COMPONENT16;
840 case D3DFMT_D24S8:
841 return GL_DEPTH24_STENCIL8_OES;
842 default:
843 UNREACHABLE();
844 }
845
846 return GL_DEPTH24_STENCIL8_OES;
847}
848
849}