blob: 01cca3c05f71e5ffcb47be8b9c40e3eca72046e8 [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>
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000012#include <stdio.h>
13#include <windows.h>
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +000014
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000015#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000016
17#include "libGLESv2/mathutil.h"
18#include "libGLESv2/Context.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000019
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000020namespace gl
21{
22
23int UniformComponentCount(GLenum type)
24{
25 switch (type)
26 {
27 case GL_BOOL:
28 case GL_FLOAT:
29 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000030 case GL_SAMPLER_2D:
31 case GL_SAMPLER_CUBE:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000032 return 1;
33 case GL_BOOL_VEC2:
34 case GL_FLOAT_VEC2:
35 case GL_INT_VEC2:
36 return 2;
37 case GL_INT_VEC3:
38 case GL_FLOAT_VEC3:
39 case GL_BOOL_VEC3:
40 return 3;
41 case GL_BOOL_VEC4:
42 case GL_FLOAT_VEC4:
43 case GL_INT_VEC4:
44 case GL_FLOAT_MAT2:
45 return 4;
46 case GL_FLOAT_MAT3:
47 return 9;
48 case GL_FLOAT_MAT4:
49 return 16;
50 default:
51 UNREACHABLE();
52 }
53
54 return 0;
55}
56
57GLenum UniformComponentType(GLenum type)
58{
59 switch(type)
60 {
61 case GL_BOOL:
62 case GL_BOOL_VEC2:
63 case GL_BOOL_VEC3:
64 case GL_BOOL_VEC4:
65 return GL_BOOL;
66 case GL_FLOAT:
67 case GL_FLOAT_VEC2:
68 case GL_FLOAT_VEC3:
69 case GL_FLOAT_VEC4:
70 case GL_FLOAT_MAT2:
71 case GL_FLOAT_MAT3:
72 case GL_FLOAT_MAT4:
73 return GL_FLOAT;
74 case GL_INT:
daniel@transgaming.coma9cd70a2010-09-15 15:48:57 +000075 case GL_SAMPLER_2D:
76 case GL_SAMPLER_CUBE:
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000077 case GL_INT_VEC2:
78 case GL_INT_VEC3:
79 case GL_INT_VEC4:
80 return GL_INT;
81 default:
82 UNREACHABLE();
83 }
84
85 return GL_NONE;
86}
87
88size_t UniformTypeSize(GLenum type)
89{
90 switch(type)
91 {
92 case GL_BOOL: return sizeof(GLboolean);
93 case GL_FLOAT: return sizeof(GLfloat);
94 case GL_INT: return sizeof(GLint);
95 }
96
97 return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
98}
99
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000100int VariableRowCount(GLenum type)
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000101{
102 switch (type)
103 {
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000104 case GL_NONE:
105 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000106 case GL_BOOL:
107 case GL_FLOAT:
108 case GL_INT:
109 case GL_BOOL_VEC2:
110 case GL_FLOAT_VEC2:
111 case GL_INT_VEC2:
112 case GL_INT_VEC3:
113 case GL_FLOAT_VEC3:
114 case GL_BOOL_VEC3:
115 case GL_BOOL_VEC4:
116 case GL_FLOAT_VEC4:
117 case GL_INT_VEC4:
118 return 1;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000119 case GL_FLOAT_MAT2:
120 return 2;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000121 case GL_FLOAT_MAT3:
122 return 3;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000123 case GL_FLOAT_MAT4:
124 return 4;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000125 default:
126 UNREACHABLE();
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000127 }
daniel@transgaming.com4af7acc2010-05-14 17:30:53 +0000128
129 return 0;
130}
131
132int VariableColumnCount(GLenum type)
133{
134 switch (type)
135 {
136 case GL_NONE:
137 return 0;
138 case GL_BOOL:
139 case GL_FLOAT:
140 case GL_INT:
141 return 1;
142 case GL_BOOL_VEC2:
143 case GL_FLOAT_VEC2:
144 case GL_INT_VEC2:
145 case GL_FLOAT_MAT2:
146 return 2;
147 case GL_INT_VEC3:
148 case GL_FLOAT_VEC3:
149 case GL_BOOL_VEC3:
150 case GL_FLOAT_MAT3:
151 return 3;
152 case GL_BOOL_VEC4:
153 case GL_FLOAT_VEC4:
154 case GL_INT_VEC4:
155 case GL_FLOAT_MAT4:
156 return 4;
157 default:
158 UNREACHABLE();
159 }
160
161 return 0;
daniel@transgaming.com0b6b8342010-04-26 15:33:45 +0000162}
163
164int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
165{
166 ASSERT(allocationSize <= bitsSize);
167
168 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
169
170 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
171 {
172 if ((*bits & mask) == 0)
173 {
174 *bits |= mask;
175 return i;
176 }
177
178 mask <<= 1;
179 }
180
181 return -1;
182}
183
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000184GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
185{
186 ASSERT(alignment > 0 && isPow2(alignment));
187
188 GLsizei rawPitch = ComputePixelSize(format, type) * width;
189 return (rawPitch + alignment - 1) & ~(alignment - 1);
190}
191
daniel@transgaming.com01868132010-08-24 19:21:17 +0000192GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
193{
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +0000194 return ComputeCompressedSize(width, 1, format);
daniel@transgaming.com01868132010-08-24 19:21:17 +0000195}
196
197GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
198{
199 switch (format)
200 {
201 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
202 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000203 return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
daniel@transgaming.com01868132010-08-24 19:21:17 +0000204 break;
gman@chromium.org50c526d2011-08-10 05:19:44 +0000205 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
206 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
207 return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
daniel@transgaming.com01868132010-08-24 19:21:17 +0000208 default:
209 return 0;
210 }
211
daniel@transgaming.com01868132010-08-24 19:21:17 +0000212}
213
214bool IsCompressed(GLenum format)
215{
216 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
gman@chromium.org50c526d2011-08-10 05:19:44 +0000217 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
218 format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE ||
219 format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
daniel@transgaming.com01868132010-08-24 19:21:17 +0000220 {
221 return true;
222 }
223 else
224 {
225 return false;
226 }
227}
228
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000229// Returns the size, in bytes, of a single texel in an Image
230int ComputePixelSize(GLenum format, GLenum type)
231{
232 switch (type)
233 {
234 case GL_UNSIGNED_BYTE:
235 switch (format)
236 {
237 case GL_ALPHA: return sizeof(unsigned char);
238 case GL_LUMINANCE: return sizeof(unsigned char);
239 case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
240 case GL_RGB: return sizeof(unsigned char) * 3;
241 case GL_RGBA: return sizeof(unsigned char) * 4;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000242 case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000243 default: UNREACHABLE();
244 }
245 break;
246 case GL_UNSIGNED_SHORT_4_4_4_4:
247 case GL_UNSIGNED_SHORT_5_5_5_1:
248 case GL_UNSIGNED_SHORT_5_6_5:
249 return sizeof(unsigned short);
daniel@transgaming.com0a337e92010-08-28 17:38:27 +0000250 case GL_FLOAT:
251 switch (format)
252 {
253 case GL_ALPHA: return sizeof(float);
254 case GL_LUMINANCE: return sizeof(float);
255 case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
256 case GL_RGB: return sizeof(float) * 3;
257 case GL_RGBA: return sizeof(float) * 4;
258 default: UNREACHABLE();
259 }
260 break;
261 case GL_HALF_FLOAT_OES:
262 switch (format)
263 {
264 case GL_ALPHA: return sizeof(unsigned short);
265 case GL_LUMINANCE: return sizeof(unsigned short);
266 case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
267 case GL_RGB: return sizeof(unsigned short) * 3;
268 case GL_RGBA: return sizeof(unsigned short) * 4;
269 default: UNREACHABLE();
270 }
271 break;
daniel@transgaming.com713914b2010-05-04 03:35:17 +0000272 default: UNREACHABLE();
273 }
274
275 return 0;
276}
277
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000278bool IsCubemapTextureTarget(GLenum target)
279{
280 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
281}
282
283bool IsTextureTarget(GLenum target)
284{
285 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
286}
287
288// Verify that format/type are one of the combinations from table 3.4.
289bool CheckTextureFormatType(GLenum format, GLenum type)
290{
291 switch (type)
292 {
293 case GL_UNSIGNED_BYTE:
294 switch (format)
295 {
296 case GL_RGBA:
daniel@transgaming.coma9198d92010-08-08 04:49:56 +0000297 case GL_BGRA_EXT:
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000298 case GL_RGB:
299 case GL_ALPHA:
300 case GL_LUMINANCE:
301 case GL_LUMINANCE_ALPHA:
302 return true;
303
304 default:
305 return false;
306 }
307
daniel@transgaming.com0a337e92010-08-28 17:38:27 +0000308 case GL_FLOAT:
309 case GL_HALF_FLOAT_OES:
310 switch (format)
311 {
312 case GL_RGBA:
313 case GL_RGB:
314 case GL_ALPHA:
315 case GL_LUMINANCE:
316 case GL_LUMINANCE_ALPHA:
317 return true;
318
319 default:
320 return false;
321 }
322
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000323 case GL_UNSIGNED_SHORT_4_4_4_4:
324 case GL_UNSIGNED_SHORT_5_5_5_1:
325 return (format == GL_RGBA);
326
327 case GL_UNSIGNED_SHORT_5_6_5:
328 return (format == GL_RGB);
329
330 default:
331 return false;
332 }
333}
334
daniel@transgaming.comedc19182010-10-15 17:57:55 +0000335bool IsColorRenderable(GLenum internalformat)
336{
337 switch (internalformat)
338 {
339 case GL_RGBA4:
340 case GL_RGB5_A1:
341 case GL_RGB565:
342 case GL_RGB8_OES:
343 case GL_RGBA8_OES:
344 return true;
345 case GL_DEPTH_COMPONENT16:
346 case GL_STENCIL_INDEX8:
347 case GL_DEPTH24_STENCIL8_OES:
348 return false;
349 default:
350 UNIMPLEMENTED();
351 }
352
353 return false;
354}
355
356bool IsDepthRenderable(GLenum internalformat)
357{
358 switch (internalformat)
359 {
360 case GL_DEPTH_COMPONENT16:
361 case GL_DEPTH24_STENCIL8_OES:
362 return true;
363 case GL_STENCIL_INDEX8:
364 case GL_RGBA4:
365 case GL_RGB5_A1:
366 case GL_RGB565:
367 case GL_RGB8_OES:
368 case GL_RGBA8_OES:
369 return false;
370 default:
371 UNIMPLEMENTED();
372 }
373
374 return false;
375}
376
377bool IsStencilRenderable(GLenum internalformat)
378{
379 switch (internalformat)
380 {
381 case GL_STENCIL_INDEX8:
382 case GL_DEPTH24_STENCIL8_OES:
383 return true;
384 case GL_RGBA4:
385 case GL_RGB5_A1:
386 case GL_RGB565:
387 case GL_RGB8_OES:
388 case GL_RGBA8_OES:
389 case GL_DEPTH_COMPONENT16:
390 return false;
391 default:
392 UNIMPLEMENTED();
393 }
394
395 return false;
396}
397
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +0000398}
399
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000400namespace es2dx
401{
402
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000403D3DCMPFUNC ConvertComparison(GLenum comparison)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000404{
405 D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
406 switch (comparison)
407 {
408 case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
409 case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
410 case GL_LESS: d3dComp = D3DCMP_LESS; break;
411 case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
412 case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
413 case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
414 case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
415 case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
416 default: UNREACHABLE();
417 }
418
419 return d3dComp;
420}
421
422D3DCOLOR ConvertColor(gl::Color color)
423{
424 return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000425 gl::unorm<8>(color.green),
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000426 gl::unorm<8>(color.blue),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000427 gl::unorm<8>(color.alpha));
428}
429
430D3DBLEND ConvertBlendFunc(GLenum blend)
431{
432 D3DBLEND d3dBlend = D3DBLEND_ZERO;
433
434 switch (blend)
435 {
436 case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
437 case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
438 case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
439 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
440 case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
441 case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
442 case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
443 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
444 case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
445 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
446 case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
447 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
448 case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
449 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
450 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
451 default: UNREACHABLE();
452 }
453
454 return d3dBlend;
455}
456
457D3DBLENDOP ConvertBlendOp(GLenum blendOp)
458{
459 D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
460
461 switch (blendOp)
462 {
463 case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
464 case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
465 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
466 default: UNREACHABLE();
467 }
468
469 return d3dBlendOp;
470}
471
472D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
473{
474 D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
475
476 switch (stencilOp)
477 {
478 case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
479 case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
480 case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
481 case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
482 case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
483 case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
484 case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
485 case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
486 default: UNREACHABLE();
487 }
488
489 return d3dStencilOp;
490}
491
492D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
493{
494 D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
495
496 switch (wrap)
497 {
498 case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
499 case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
500 case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
501 default: UNREACHABLE();
502 }
503
504 return d3dWrap;
505}
506
507D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
508{
509 D3DCULL cull = D3DCULL_CCW;
510 switch (cullFace)
511 {
512 case GL_FRONT:
513 cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
514 break;
515 case GL_BACK:
516 cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
517 break;
518 case GL_FRONT_AND_BACK:
daniel@transgaming.comace5e662010-03-21 04:31:20 +0000519 cull = D3DCULL_NONE; // culling will be handled during draw
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000520 break;
521 default: UNREACHABLE();
522 }
523
524 return cull;
525}
526
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +0000527D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
528{
529 D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
530
531 // Map a cube map texture target to the corresponding D3D surface index. Note that the
532 // Y faces are swapped because the Y coordinate to the texture lookup intrinsic functions
533 // are negated in the pixel shader.
534 switch (cubeFace)
535 {
536 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
537 face = D3DCUBEMAP_FACE_POSITIVE_X;
538 break;
539 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
540 face = D3DCUBEMAP_FACE_NEGATIVE_X;
541 break;
542 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
543 face = D3DCUBEMAP_FACE_NEGATIVE_Y;
544 break;
545 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
546 face = D3DCUBEMAP_FACE_POSITIVE_Y;
547 break;
548 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
549 face = D3DCUBEMAP_FACE_POSITIVE_Z;
550 break;
551 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
552 face = D3DCUBEMAP_FACE_NEGATIVE_Z;
553 break;
554 default: UNREACHABLE();
555 }
556
557 return face;
558}
559
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000560DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
561{
562 return (red ? D3DCOLORWRITEENABLE_RED : 0) |
563 (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
564 (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
565 (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
566}
567
568D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
569{
570 D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
571 switch (magFilter)
572 {
573 case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
574 case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
575 default: UNREACHABLE();
576 }
577
578 return d3dMagFilter;
579}
580
581void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
582{
583 switch (minFilter)
584 {
585 case GL_NEAREST:
586 *d3dMinFilter = D3DTEXF_POINT;
587 *d3dMipFilter = D3DTEXF_NONE;
588 break;
589 case GL_LINEAR:
590 *d3dMinFilter = D3DTEXF_LINEAR;
591 *d3dMipFilter = D3DTEXF_NONE;
592 break;
593 case GL_NEAREST_MIPMAP_NEAREST:
594 *d3dMinFilter = D3DTEXF_POINT;
595 *d3dMipFilter = D3DTEXF_POINT;
596 break;
597 case GL_LINEAR_MIPMAP_NEAREST:
598 *d3dMinFilter = D3DTEXF_LINEAR;
599 *d3dMipFilter = D3DTEXF_POINT;
600 break;
601 case GL_NEAREST_MIPMAP_LINEAR:
602 *d3dMinFilter = D3DTEXF_POINT;
603 *d3dMipFilter = D3DTEXF_LINEAR;
604 break;
605 case GL_LINEAR_MIPMAP_LINEAR:
606 *d3dMinFilter = D3DTEXF_LINEAR;
607 *d3dMipFilter = D3DTEXF_LINEAR;
608 break;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000609 default:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000610 *d3dMinFilter = D3DTEXF_POINT;
611 *d3dMipFilter = D3DTEXF_NONE;
612 UNREACHABLE();
613 }
614}
615
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000616bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
617 D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
618{
619 switch (primitiveType)
620 {
621 case GL_POINTS:
622 *d3dPrimitiveType = D3DPT_POINTLIST;
623 *d3dPrimitiveCount = elementCount;
624 break;
625 case GL_LINES:
626 *d3dPrimitiveType = D3DPT_LINELIST;
627 *d3dPrimitiveCount = elementCount / 2;
628 break;
629 case GL_LINE_LOOP:
630 *d3dPrimitiveType = D3DPT_LINESTRIP;
631 *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
632 break;
633 case GL_LINE_STRIP:
634 *d3dPrimitiveType = D3DPT_LINESTRIP;
635 *d3dPrimitiveCount = elementCount - 1;
636 break;
637 case GL_TRIANGLES:
638 *d3dPrimitiveType = D3DPT_TRIANGLELIST;
639 *d3dPrimitiveCount = elementCount / 3;
640 break;
641 case GL_TRIANGLE_STRIP:
642 *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
643 *d3dPrimitiveCount = elementCount - 2;
644 break;
645 case GL_TRIANGLE_FAN:
646 *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
647 *d3dPrimitiveCount = elementCount - 2;
648 break;
649 default:
650 return false;
651 }
652
653 return true;
654}
655
656D3DFORMAT ConvertRenderbufferFormat(GLenum format)
657{
658 switch (format)
659 {
660 case GL_RGBA4:
661 case GL_RGB5_A1:
662 case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
663 case GL_RGB565: return D3DFMT_R5G6B5;
664 case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
665 case GL_DEPTH_COMPONENT16:
666 case GL_STENCIL_INDEX8:
667 case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
668 default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
669 }
670}
671
672D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
673{
674 if (samples <= 1)
675 return D3DMULTISAMPLE_NONE;
676 else
677 return (D3DMULTISAMPLE_TYPE)samples;
678}
679
680}
681
682namespace dx2es
683{
684
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000685unsigned int GetStencilSize(D3DFORMAT stencilFormat)
686{
687 switch(stencilFormat)
688 {
689 case D3DFMT_D24FS8:
690 case D3DFMT_D24S8:
691 return 8;
692 case D3DFMT_D24X4S4:
693 return 4;
694 case D3DFMT_D15S1:
695 return 1;
696 case D3DFMT_D16_LOCKABLE:
697 case D3DFMT_D32:
698 case D3DFMT_D24X8:
699 case D3DFMT_D32F_LOCKABLE:
700 case D3DFMT_D16:
701 return 0;
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000702 //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
703 //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000704 default:
705 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000706 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000707}
708
709unsigned int GetAlphaSize(D3DFORMAT colorFormat)
710{
711 switch (colorFormat)
712 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000713 case D3DFMT_A16B16G16R16F:
714 return 16;
715 case D3DFMT_A32B32G32R32F:
716 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000717 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000718 return 2;
719 case D3DFMT_A8R8G8B8:
720 return 8;
721 case D3DFMT_A1R5G5B5:
722 return 1;
723 case D3DFMT_X8R8G8B8:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000724 case D3DFMT_R5G6B5:
725 return 0;
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000726 default:
727 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729}
730
731unsigned int GetRedSize(D3DFORMAT colorFormat)
732{
733 switch (colorFormat)
734 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000735 case D3DFMT_A16B16G16R16F:
736 return 16;
737 case D3DFMT_A32B32G32R32F:
738 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000739 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000740 return 10;
741 case D3DFMT_A8R8G8B8:
742 case D3DFMT_X8R8G8B8:
743 return 8;
744 case D3DFMT_A1R5G5B5:
745 case D3DFMT_R5G6B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000746 return 5;
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000747 default:
748 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000749 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000750}
751
752unsigned int GetGreenSize(D3DFORMAT colorFormat)
753{
754 switch (colorFormat)
755 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000756 case D3DFMT_A16B16G16R16F:
757 return 16;
758 case D3DFMT_A32B32G32R32F:
759 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000760 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000761 return 10;
762 case D3DFMT_A8R8G8B8:
763 case D3DFMT_X8R8G8B8:
764 return 8;
765 case D3DFMT_A1R5G5B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000766 return 5;
767 case D3DFMT_R5G6B5:
768 return 6;
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000769 default:
770 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000772}
773
774unsigned int GetBlueSize(D3DFORMAT colorFormat)
775{
776 switch (colorFormat)
777 {
daniel@transgaming.com1297d922010-09-01 15:47:47 +0000778 case D3DFMT_A16B16G16R16F:
779 return 16;
780 case D3DFMT_A32B32G32R32F:
781 return 32;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000782 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000783 return 10;
784 case D3DFMT_A8R8G8B8:
785 case D3DFMT_X8R8G8B8:
786 return 8;
787 case D3DFMT_A1R5G5B5:
788 case D3DFMT_R5G6B5:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000789 return 5;
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000790 default:
791 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000792 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000793}
794
795unsigned int GetDepthSize(D3DFORMAT depthFormat)
796{
797 switch (depthFormat)
798 {
799 case D3DFMT_D16_LOCKABLE: return 16;
800 case D3DFMT_D32: return 32;
801 case D3DFMT_D15S1: return 15;
802 case D3DFMT_D24S8: return 24;
803 case D3DFMT_D24X8: return 24;
804 case D3DFMT_D24X4S4: return 24;
805 case D3DFMT_D16: return 16;
806 case D3DFMT_D32F_LOCKABLE: return 32;
807 case D3DFMT_D24FS8: return 24;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000808 //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
809 //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
apatrick@chromium.org831fe2a2011-03-17 18:44:29 +0000810 default: return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000811 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000812}
813
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000814GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
815{
816 if (type == D3DMULTISAMPLE_NONMASKABLE)
817 return 0;
818 else
819 return type;
820}
821
daniel@transgaming.com73a5db62010-10-15 17:58:13 +0000822GLenum ConvertBackBufferFormat(D3DFORMAT format)
823{
824 switch (format)
825 {
826 case D3DFMT_A4R4G4B4: return GL_RGBA4;
827 case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
828 case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
829 case D3DFMT_R5G6B5: return GL_RGB565;
830 case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
831 default:
832 UNREACHABLE();
833 }
834
835 return GL_RGBA4;
836}
837
838GLenum ConvertDepthStencilFormat(D3DFORMAT format)
839{
840 switch (format)
841 {
842 case D3DFMT_D16:
843 case D3DFMT_D24X8:
844 return GL_DEPTH_COMPONENT16;
845 case D3DFMT_D24S8:
846 return GL_DEPTH24_STENCIL8_OES;
847 default:
848 UNREACHABLE();
849 }
850
851 return GL_DEPTH24_STENCIL8_OES;
852}
853
854}
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000855
856std::string getTempPath()
857{
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000858 char path[MAX_PATH];
859 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
860 if (pathLen == 0)
861 {
862 UNREACHABLE();
863 return std::string();
864 }
865
866 UINT unique = GetTempFileNameA(path, "sh", 0, path);
867 if (unique == 0)
868 {
869 UNREACHABLE();
870 return std::string();
871 }
872
873 return path;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000874}
875
876void writeFile(const char* path, const void* content, size_t size)
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +0000877{
878 FILE* file = fopen(path, "w");
879 if (!file)
880 {
881 UNREACHABLE();
882 return;
883 }
884
885 fwrite(content, sizeof(char), size, file);
886 fclose(file);
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000887}