• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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