blob: 48156625d4d306cbd210e80479a54ed15655051d [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{
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
206GLsizei 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
220bool 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
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000233// Returns the size, in bytes, of a single texel in an Image
234int 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;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000246 case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000247 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);
daniel@transgaming.com0a337e92010-08-28 17:38:27 +0000254 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;
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000276 default: UNREACHABLE();
277 }
278
279 return 0;
280}
281
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000282bool IsCubemapTextureTarget(GLenum target)
283{
284 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
285}
286
287bool 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.
293bool CheckTextureFormatType(GLenum format, GLenum type)
294{
295 switch (type)
296 {
297 case GL_UNSIGNED_BYTE:
298 switch (format)
299 {
300 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000301 case GL_BGRA_EXT:
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000302 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
daniel@transgaming.com0a337e92010-08-28 17:38:27 +0000312 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
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000327 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
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000339bool 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
360bool 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
381bool 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
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000402}
403
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000404namespace es2dx
405{
406
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000407D3DCMPFUNC ConvertComparison(GLenum comparison)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000408{
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
426D3DCOLOR ConvertColor(gl::Color color)
427{
428 return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000429 gl::unorm<8>(color.green),
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000430 gl::unorm<8>(color.blue),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000431 gl::unorm<8>(color.alpha));
432}
433
434D3DBLEND 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
461D3DBLENDOP 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
476D3DSTENCILOP 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
496D3DTEXTUREADDRESS 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
511D3DCULL 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:
daniel@transgaming.comace5e662010-03-21 04:31:20 +0000523 cull = D3DCULL_NONE; // culling will be handled during draw
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000524 break;
525 default: UNREACHABLE();
526 }
527
528 return cull;
529}
530
531DWORD 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
539D3DTEXTUREFILTERTYPE 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
552void 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;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000580 default:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000581 *d3dMinFilter = D3DTEXF_POINT;
582 *d3dMipFilter = D3DTEXF_NONE;
583 UNREACHABLE();
584 }
585}
586
587unsigned 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
611unsigned int GetAlphaSize(D3DFORMAT colorFormat)
612{
613 switch (colorFormat)
614 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000615 case D3DFMT_A16B16G16R16F:
616 return 16;
617 case D3DFMT_A32B32G32R32F:
618 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000619 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000620 return 2;
621 case D3DFMT_A8R8G8B8:
622 return 8;
623 case D3DFMT_A1R5G5B5:
624 return 1;
625 case D3DFMT_X8R8G8B8:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000626 case D3DFMT_R5G6B5:
627 return 0;
628 default: UNREACHABLE();
629 }
630 return 0;
631}
632
633unsigned int GetRedSize(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 10;
643 case D3DFMT_A8R8G8B8:
644 case D3DFMT_X8R8G8B8:
645 return 8;
646 case D3DFMT_A1R5G5B5:
647 case D3DFMT_R5G6B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000648 return 5;
649 default: UNREACHABLE();
650 }
651 return 0;
652}
653
654unsigned int GetGreenSize(D3DFORMAT colorFormat)
655{
656 switch (colorFormat)
657 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000658 case D3DFMT_A16B16G16R16F:
659 return 16;
660 case D3DFMT_A32B32G32R32F:
661 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000662 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000663 return 10;
664 case D3DFMT_A8R8G8B8:
665 case D3DFMT_X8R8G8B8:
666 return 8;
667 case D3DFMT_A1R5G5B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000668 return 5;
669 case D3DFMT_R5G6B5:
670 return 6;
671 default: UNREACHABLE();
672 }
673 return 0;
674}
675
676unsigned int GetBlueSize(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:
690 case D3DFMT_R5G6B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000691 return 5;
692 default: UNREACHABLE();
693 }
694 return 0;
695}
696
697unsigned 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
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000718bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000719 D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
720{
721 switch (primitiveType)
722 {
723 case GL_POINTS:
724 *d3dPrimitiveType = D3DPT_POINTLIST;
725 *d3dPrimitiveCount = primitiveCount;
726 break;
727 case GL_LINES:
728 *d3dPrimitiveType = D3DPT_LINELIST;
729 *d3dPrimitiveCount = primitiveCount / 2;
730 break;
731 case GL_LINE_LOOP:
daniel@transgaming.combf2b52a2010-04-20 18:53:03 +0000732 *d3dPrimitiveType = D3DPT_LINESTRIP;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000733 *d3dPrimitiveCount = primitiveCount;
734 break;
735 case GL_LINE_STRIP:
736 *d3dPrimitiveType = D3DPT_LINESTRIP;
737 *d3dPrimitiveCount = primitiveCount - 1;
738 break;
739 case GL_TRIANGLES:
740 *d3dPrimitiveType = D3DPT_TRIANGLELIST;
741 *d3dPrimitiveCount = primitiveCount / 3;
742 break;
743 case GL_TRIANGLE_STRIP:
744 *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
745 *d3dPrimitiveCount = primitiveCount - 2;
746 break;
747 case GL_TRIANGLE_FAN:
748 *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
749 *d3dPrimitiveCount = primitiveCount - 2;
750 break;
751 default:
752 return false;
753 }
754
755 return true;
756}
757
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000758D3DFORMAT ConvertRenderbufferFormat(GLenum format)
759{
760 switch (format)
761 {
762 case GL_RGBA4:
daniel@transgaming.com63977542010-08-24 19:21:02 +0000763 case GL_RGB5_A1:
764 case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000765 case GL_RGB565: return D3DFMT_R5G6B5;
daniel@transgaming.com63977542010-08-24 19:21:02 +0000766 case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000767 case GL_DEPTH_COMPONENT16:
daniel@transgaming.comca7c0082010-08-24 19:20:20 +0000768 case GL_STENCIL_INDEX8:
769 case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000770 default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
771 }
772}
773
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000774GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
775{
776 if (type == D3DMULTISAMPLE_NONMASKABLE)
777 return 0;
778 else
779 return type;
780}
781
782D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
783{
784 if (samples <= 1)
785 return D3DMULTISAMPLE_NONE;
786 else
787 return (D3DMULTISAMPLE_TYPE)samples;
788}
789
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000790}
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000791
792namespace dx2es
793{
794
795GLenum 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
811GLenum 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}