1 //
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
9 #include "libGLESv2/utilities.h"
10
11 #include <limits>
12
13 #include "common/debug.h"
14
15 #include "libGLESv2/mathutil.h"
16 #include "libGLESv2/Context.h"
17
18 namespace gl
19 {
20
UniformComponentCount(GLenum type)21 int UniformComponentCount(GLenum type)
22 {
23 switch (type)
24 {
25 case GL_BOOL:
26 case GL_FLOAT:
27 case GL_INT:
28 case GL_SAMPLER_2D:
29 case GL_SAMPLER_CUBE:
30 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
UniformComponentType(GLenum type)55 GLenum 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:
73 case GL_SAMPLER_2D:
74 case GL_SAMPLER_CUBE:
75 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
UniformTypeSize(GLenum type)86 size_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
VariableRowCount(GLenum type)98 int VariableRowCount(GLenum type)
99 {
100 switch (type)
101 {
102 case GL_NONE:
103 return 0;
104 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;
117 case GL_FLOAT_MAT2:
118 return 2;
119 case GL_FLOAT_MAT3:
120 return 3;
121 case GL_FLOAT_MAT4:
122 return 4;
123 default:
124 UNREACHABLE();
125 }
126
127 return 0;
128 }
129
VariableColumnCount(GLenum type)130 int 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;
160 }
161
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)162 int 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
ComputePitch(GLsizei width,GLenum format,GLenum type,GLint alignment)182 GLsizei 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
ComputeCompressedPitch(GLsizei width,GLenum format)190 GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
191 {
192 switch (format)
193 {
194 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
195 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
196 break;
197 default:
198 return 0;
199 }
200
201 ASSERT(width % 4 == 0);
202
203 return 8 * width / 4;
204 }
205
ComputeCompressedSize(GLsizei width,GLsizei height,GLenum format)206 GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
207 {
208 switch (format)
209 {
210 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
211 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
212 break;
213 default:
214 return 0;
215 }
216
217 return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
218 }
219
IsCompressed(GLenum format)220 bool IsCompressed(GLenum format)
221 {
222 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
223 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
224 {
225 return true;
226 }
227 else
228 {
229 return false;
230 }
231 }
232
233 // Returns the size, in bytes, of a single texel in an Image
ComputePixelSize(GLenum format,GLenum type)234 int ComputePixelSize(GLenum format, GLenum type)
235 {
236 switch (type)
237 {
238 case GL_UNSIGNED_BYTE:
239 switch (format)
240 {
241 case GL_ALPHA: return sizeof(unsigned char);
242 case GL_LUMINANCE: return sizeof(unsigned char);
243 case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
244 case GL_RGB: return sizeof(unsigned char) * 3;
245 case GL_RGBA: return sizeof(unsigned char) * 4;
246 case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
247 default: UNREACHABLE();
248 }
249 break;
250 case GL_UNSIGNED_SHORT_4_4_4_4:
251 case GL_UNSIGNED_SHORT_5_5_5_1:
252 case GL_UNSIGNED_SHORT_5_6_5:
253 return sizeof(unsigned short);
254 case GL_FLOAT:
255 switch (format)
256 {
257 case GL_ALPHA: return sizeof(float);
258 case GL_LUMINANCE: return sizeof(float);
259 case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
260 case GL_RGB: return sizeof(float) * 3;
261 case GL_RGBA: return sizeof(float) * 4;
262 default: UNREACHABLE();
263 }
264 break;
265 case GL_HALF_FLOAT_OES:
266 switch (format)
267 {
268 case GL_ALPHA: return sizeof(unsigned short);
269 case GL_LUMINANCE: return sizeof(unsigned short);
270 case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
271 case GL_RGB: return sizeof(unsigned short) * 3;
272 case GL_RGBA: return sizeof(unsigned short) * 4;
273 default: UNREACHABLE();
274 }
275 break;
276 default: UNREACHABLE();
277 }
278
279 return 0;
280 }
281
IsCubemapTextureTarget(GLenum target)282 bool IsCubemapTextureTarget(GLenum target)
283 {
284 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
285 }
286
IsTextureTarget(GLenum target)287 bool IsTextureTarget(GLenum target)
288 {
289 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
290 }
291
292 // Verify that format/type are one of the combinations from table 3.4.
CheckTextureFormatType(GLenum format,GLenum type)293 bool CheckTextureFormatType(GLenum format, GLenum type)
294 {
295 switch (type)
296 {
297 case GL_UNSIGNED_BYTE:
298 switch (format)
299 {
300 case GL_RGBA:
301 case GL_BGRA_EXT:
302 case GL_RGB:
303 case GL_ALPHA:
304 case GL_LUMINANCE:
305 case GL_LUMINANCE_ALPHA:
306 return true;
307
308 default:
309 return false;
310 }
311
312 case GL_FLOAT:
313 case GL_HALF_FLOAT_OES:
314 switch (format)
315 {
316 case GL_RGBA:
317 case GL_RGB:
318 case GL_ALPHA:
319 case GL_LUMINANCE:
320 case GL_LUMINANCE_ALPHA:
321 return true;
322
323 default:
324 return false;
325 }
326
327 case GL_UNSIGNED_SHORT_4_4_4_4:
328 case GL_UNSIGNED_SHORT_5_5_5_1:
329 return (format == GL_RGBA);
330
331 case GL_UNSIGNED_SHORT_5_6_5:
332 return (format == GL_RGB);
333
334 default:
335 return false;
336 }
337 }
338
IsColorRenderable(GLenum internalformat)339 bool IsColorRenderable(GLenum internalformat)
340 {
341 switch (internalformat)
342 {
343 case GL_RGBA4:
344 case GL_RGB5_A1:
345 case GL_RGB565:
346 case GL_RGB8_OES:
347 case GL_RGBA8_OES:
348 return true;
349 case GL_DEPTH_COMPONENT16:
350 case GL_STENCIL_INDEX8:
351 case GL_DEPTH24_STENCIL8_OES:
352 return false;
353 default:
354 UNIMPLEMENTED();
355 }
356
357 return false;
358 }
359
IsDepthRenderable(GLenum internalformat)360 bool IsDepthRenderable(GLenum internalformat)
361 {
362 switch (internalformat)
363 {
364 case GL_DEPTH_COMPONENT16:
365 case GL_DEPTH24_STENCIL8_OES:
366 return true;
367 case GL_STENCIL_INDEX8:
368 case GL_RGBA4:
369 case GL_RGB5_A1:
370 case GL_RGB565:
371 case GL_RGB8_OES:
372 case GL_RGBA8_OES:
373 return false;
374 default:
375 UNIMPLEMENTED();
376 }
377
378 return false;
379 }
380
IsStencilRenderable(GLenum internalformat)381 bool IsStencilRenderable(GLenum internalformat)
382 {
383 switch (internalformat)
384 {
385 case GL_STENCIL_INDEX8:
386 case GL_DEPTH24_STENCIL8_OES:
387 return true;
388 case GL_RGBA4:
389 case GL_RGB5_A1:
390 case GL_RGB565:
391 case GL_RGB8_OES:
392 case GL_RGBA8_OES:
393 case GL_DEPTH_COMPONENT16:
394 return false;
395 default:
396 UNIMPLEMENTED();
397 }
398
399 return false;
400 }
401
402 }
403
404 namespace es2dx
405 {
406
ConvertComparison(GLenum comparison)407 D3DCMPFUNC ConvertComparison(GLenum comparison)
408 {
409 D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
410 switch (comparison)
411 {
412 case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
413 case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
414 case GL_LESS: d3dComp = D3DCMP_LESS; break;
415 case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
416 case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
417 case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
418 case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
419 case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
420 default: UNREACHABLE();
421 }
422
423 return d3dComp;
424 }
425
ConvertColor(gl::Color color)426 D3DCOLOR ConvertColor(gl::Color color)
427 {
428 return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
429 gl::unorm<8>(color.green),
430 gl::unorm<8>(color.blue),
431 gl::unorm<8>(color.alpha));
432 }
433
ConvertBlendFunc(GLenum blend)434 D3DBLEND ConvertBlendFunc(GLenum blend)
435 {
436 D3DBLEND d3dBlend = D3DBLEND_ZERO;
437
438 switch (blend)
439 {
440 case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
441 case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
442 case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
443 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
444 case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
445 case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
446 case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
447 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
448 case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
449 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
450 case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
451 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
452 case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
453 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
454 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
455 default: UNREACHABLE();
456 }
457
458 return d3dBlend;
459 }
460
ConvertBlendOp(GLenum blendOp)461 D3DBLENDOP ConvertBlendOp(GLenum blendOp)
462 {
463 D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
464
465 switch (blendOp)
466 {
467 case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
468 case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
469 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
470 default: UNREACHABLE();
471 }
472
473 return d3dBlendOp;
474 }
475
ConvertStencilOp(GLenum stencilOp)476 D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
477 {
478 D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
479
480 switch (stencilOp)
481 {
482 case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
483 case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
484 case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
485 case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
486 case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
487 case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
488 case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
489 case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
490 default: UNREACHABLE();
491 }
492
493 return d3dStencilOp;
494 }
495
ConvertTextureWrap(GLenum wrap)496 D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
497 {
498 D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
499
500 switch (wrap)
501 {
502 case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
503 case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
504 case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
505 default: UNREACHABLE();
506 }
507
508 return d3dWrap;
509 }
510
ConvertCullMode(GLenum cullFace,GLenum frontFace)511 D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
512 {
513 D3DCULL cull = D3DCULL_CCW;
514 switch (cullFace)
515 {
516 case GL_FRONT:
517 cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
518 break;
519 case GL_BACK:
520 cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
521 break;
522 case GL_FRONT_AND_BACK:
523 cull = D3DCULL_NONE; // culling will be handled during draw
524 break;
525 default: UNREACHABLE();
526 }
527
528 return cull;
529 }
530
ConvertColorMask(bool red,bool green,bool blue,bool alpha)531 DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
532 {
533 return (red ? D3DCOLORWRITEENABLE_RED : 0) |
534 (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
535 (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
536 (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
537 }
538
ConvertMagFilter(GLenum magFilter)539 D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
540 {
541 D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
542 switch (magFilter)
543 {
544 case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
545 case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
546 default: UNREACHABLE();
547 }
548
549 return d3dMagFilter;
550 }
551
ConvertMinFilter(GLenum minFilter,D3DTEXTUREFILTERTYPE * d3dMinFilter,D3DTEXTUREFILTERTYPE * d3dMipFilter)552 void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
553 {
554 switch (minFilter)
555 {
556 case GL_NEAREST:
557 *d3dMinFilter = D3DTEXF_POINT;
558 *d3dMipFilter = D3DTEXF_NONE;
559 break;
560 case GL_LINEAR:
561 *d3dMinFilter = D3DTEXF_LINEAR;
562 *d3dMipFilter = D3DTEXF_NONE;
563 break;
564 case GL_NEAREST_MIPMAP_NEAREST:
565 *d3dMinFilter = D3DTEXF_POINT;
566 *d3dMipFilter = D3DTEXF_POINT;
567 break;
568 case GL_LINEAR_MIPMAP_NEAREST:
569 *d3dMinFilter = D3DTEXF_LINEAR;
570 *d3dMipFilter = D3DTEXF_POINT;
571 break;
572 case GL_NEAREST_MIPMAP_LINEAR:
573 *d3dMinFilter = D3DTEXF_POINT;
574 *d3dMipFilter = D3DTEXF_LINEAR;
575 break;
576 case GL_LINEAR_MIPMAP_LINEAR:
577 *d3dMinFilter = D3DTEXF_LINEAR;
578 *d3dMipFilter = D3DTEXF_LINEAR;
579 break;
580 default:
581 *d3dMinFilter = D3DTEXF_POINT;
582 *d3dMipFilter = D3DTEXF_NONE;
583 UNREACHABLE();
584 }
585 }
586
GetStencilSize(D3DFORMAT stencilFormat)587 unsigned int GetStencilSize(D3DFORMAT stencilFormat)
588 {
589 switch(stencilFormat)
590 {
591 case D3DFMT_D24FS8:
592 case D3DFMT_D24S8:
593 return 8;
594 case D3DFMT_D24X4S4:
595 return 4;
596 case D3DFMT_D15S1:
597 return 1;
598 case D3DFMT_D16_LOCKABLE:
599 case D3DFMT_D32:
600 case D3DFMT_D24X8:
601 case D3DFMT_D32F_LOCKABLE:
602 case D3DFMT_D16:
603 return 0;
604 // case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
605 // case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
606 default: UNREACHABLE();
607 }
608 return 0;
609 }
610
GetAlphaSize(D3DFORMAT colorFormat)611 unsigned int GetAlphaSize(D3DFORMAT colorFormat)
612 {
613 switch (colorFormat)
614 {
615 case D3DFMT_A16B16G16R16F:
616 return 16;
617 case D3DFMT_A32B32G32R32F:
618 return 32;
619 case D3DFMT_A2R10G10B10:
620 return 2;
621 case D3DFMT_A8R8G8B8:
622 return 8;
623 case D3DFMT_A1R5G5B5:
624 return 1;
625 case D3DFMT_X8R8G8B8:
626 case D3DFMT_R5G6B5:
627 return 0;
628 default: UNREACHABLE();
629 }
630 return 0;
631 }
632
GetRedSize(D3DFORMAT colorFormat)633 unsigned int GetRedSize(D3DFORMAT colorFormat)
634 {
635 switch (colorFormat)
636 {
637 case D3DFMT_A16B16G16R16F:
638 return 16;
639 case D3DFMT_A32B32G32R32F:
640 return 32;
641 case D3DFMT_A2R10G10B10:
642 return 10;
643 case D3DFMT_A8R8G8B8:
644 case D3DFMT_X8R8G8B8:
645 return 8;
646 case D3DFMT_A1R5G5B5:
647 case D3DFMT_R5G6B5:
648 return 5;
649 default: UNREACHABLE();
650 }
651 return 0;
652 }
653
GetGreenSize(D3DFORMAT colorFormat)654 unsigned int GetGreenSize(D3DFORMAT colorFormat)
655 {
656 switch (colorFormat)
657 {
658 case D3DFMT_A16B16G16R16F:
659 return 16;
660 case D3DFMT_A32B32G32R32F:
661 return 32;
662 case D3DFMT_A2R10G10B10:
663 return 10;
664 case D3DFMT_A8R8G8B8:
665 case D3DFMT_X8R8G8B8:
666 return 8;
667 case D3DFMT_A1R5G5B5:
668 return 5;
669 case D3DFMT_R5G6B5:
670 return 6;
671 default: UNREACHABLE();
672 }
673 return 0;
674 }
675
GetBlueSize(D3DFORMAT colorFormat)676 unsigned int GetBlueSize(D3DFORMAT colorFormat)
677 {
678 switch (colorFormat)
679 {
680 case D3DFMT_A16B16G16R16F:
681 return 16;
682 case D3DFMT_A32B32G32R32F:
683 return 32;
684 case D3DFMT_A2R10G10B10:
685 return 10;
686 case D3DFMT_A8R8G8B8:
687 case D3DFMT_X8R8G8B8:
688 return 8;
689 case D3DFMT_A1R5G5B5:
690 case D3DFMT_R5G6B5:
691 return 5;
692 default: UNREACHABLE();
693 }
694 return 0;
695 }
696
GetDepthSize(D3DFORMAT depthFormat)697 unsigned int GetDepthSize(D3DFORMAT depthFormat)
698 {
699 switch (depthFormat)
700 {
701 case D3DFMT_D16_LOCKABLE: return 16;
702 case D3DFMT_D32: return 32;
703 case D3DFMT_D15S1: return 15;
704 case D3DFMT_D24S8: return 24;
705 case D3DFMT_D24X8: return 24;
706 case D3DFMT_D24X4S4: return 24;
707 case D3DFMT_D16: return 16;
708 case D3DFMT_D32F_LOCKABLE: return 32;
709 case D3DFMT_D24FS8: return 24;
710 //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
711 //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
712 default:
713 UNREACHABLE();
714 }
715 return 0;
716 }
717
ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,D3DPRIMITIVETYPE * d3dPrimitiveType,int * d3dPrimitiveCount)718 bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
719 D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
720 {
721 switch (primitiveType)
722 {
723 case GL_POINTS:
724 *d3dPrimitiveType = D3DPT_POINTLIST;
725 *d3dPrimitiveCount = elementCount;
726 break;
727 case GL_LINES:
728 *d3dPrimitiveType = D3DPT_LINELIST;
729 *d3dPrimitiveCount = elementCount / 2;
730 break;
731 case GL_LINE_LOOP:
732 *d3dPrimitiveType = D3DPT_LINESTRIP;
733 *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
734 break;
735 case GL_LINE_STRIP:
736 *d3dPrimitiveType = D3DPT_LINESTRIP;
737 *d3dPrimitiveCount = elementCount - 1;
738 break;
739 case GL_TRIANGLES:
740 *d3dPrimitiveType = D3DPT_TRIANGLELIST;
741 *d3dPrimitiveCount = elementCount / 3;
742 break;
743 case GL_TRIANGLE_STRIP:
744 *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
745 *d3dPrimitiveCount = elementCount - 2;
746 break;
747 case GL_TRIANGLE_FAN:
748 *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
749 *d3dPrimitiveCount = elementCount - 2;
750 break;
751 default:
752 return false;
753 }
754
755 return true;
756 }
757
ConvertRenderbufferFormat(GLenum format)758 D3DFORMAT ConvertRenderbufferFormat(GLenum format)
759 {
760 switch (format)
761 {
762 case GL_RGBA4:
763 case GL_RGB5_A1:
764 case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
765 case GL_RGB565: return D3DFMT_R5G6B5;
766 case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
767 case GL_DEPTH_COMPONENT16:
768 case GL_STENCIL_INDEX8:
769 case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
770 default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
771 }
772 }
773
GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)774 GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
775 {
776 if (type == D3DMULTISAMPLE_NONMASKABLE)
777 return 0;
778 else
779 return type;
780 }
781
GetMultisampleTypeFromSamples(GLsizei samples)782 D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
783 {
784 if (samples <= 1)
785 return D3DMULTISAMPLE_NONE;
786 else
787 return (D3DMULTISAMPLE_TYPE)samples;
788 }
789
790 }
791
792 namespace dx2es
793 {
794
ConvertBackBufferFormat(D3DFORMAT format)795 GLenum ConvertBackBufferFormat(D3DFORMAT format)
796 {
797 switch (format)
798 {
799 case D3DFMT_A4R4G4B4: return GL_RGBA4;
800 case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
801 case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
802 case D3DFMT_R5G6B5: return GL_RGB565;
803 case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
804 default:
805 UNREACHABLE();
806 }
807
808 return GL_RGBA4;
809 }
810
ConvertDepthStencilFormat(D3DFORMAT format)811 GLenum ConvertDepthStencilFormat(D3DFORMAT format)
812 {
813 switch (format)
814 {
815 case D3DFMT_D16:
816 case D3DFMT_D24X8:
817 return GL_DEPTH_COMPONENT16;
818 case D3DFMT_D24S8:
819 return GL_DEPTH24_STENCIL8_OES;
820 default:
821 UNREACHABLE();
822 }
823
824 return GL_DEPTH24_STENCIL8_OES;
825 }
826
827 }
828