blob: 3ea620f866c77147174cedaf8b7c17d730c71edb [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
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000011#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000012
13#include "libGLESv2/mathutil.h"
14#include "libGLESv2/Context.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015
daniel@transgaming.com1b3a8152010-04-22 13:35:37 +000016namespace gl
17{
18
19int UniformComponentCount(GLenum type)
20{
21 switch (type)
22 {
23 case GL_BOOL:
24 case GL_FLOAT:
25 case GL_INT:
26 return 1;
27 case GL_BOOL_VEC2:
28 case GL_FLOAT_VEC2:
29 case GL_INT_VEC2:
30 return 2;
31 case GL_INT_VEC3:
32 case GL_FLOAT_VEC3:
33 case GL_BOOL_VEC3:
34 return 3;
35 case GL_BOOL_VEC4:
36 case GL_FLOAT_VEC4:
37 case GL_INT_VEC4:
38 case GL_FLOAT_MAT2:
39 return 4;
40 case GL_FLOAT_MAT3:
41 return 9;
42 case GL_FLOAT_MAT4:
43 return 16;
44 default:
45 UNREACHABLE();
46 }
47
48 return 0;
49}
50
51GLenum UniformComponentType(GLenum type)
52{
53 switch(type)
54 {
55 case GL_BOOL:
56 case GL_BOOL_VEC2:
57 case GL_BOOL_VEC3:
58 case GL_BOOL_VEC4:
59 return GL_BOOL;
60 case GL_FLOAT:
61 case GL_FLOAT_VEC2:
62 case GL_FLOAT_VEC3:
63 case GL_FLOAT_VEC4:
64 case GL_FLOAT_MAT2:
65 case GL_FLOAT_MAT3:
66 case GL_FLOAT_MAT4:
67 return GL_FLOAT;
68 case GL_INT:
69 case GL_INT_VEC2:
70 case GL_INT_VEC3:
71 case GL_INT_VEC4:
72 return GL_INT;
73 default:
74 UNREACHABLE();
75 }
76
77 return GL_NONE;
78}
79
80size_t UniformTypeSize(GLenum type)
81{
82 switch(type)
83 {
84 case GL_BOOL: return sizeof(GLboolean);
85 case GL_FLOAT: return sizeof(GLfloat);
86 case GL_INT: return sizeof(GLint);
87 }
88
89 return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
90}
91
92}
93
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094namespace es2dx
95{
96
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000097D3DCMPFUNC ConvertComparison(GLenum comparison)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000098{
99 D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
100 switch (comparison)
101 {
102 case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
103 case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
104 case GL_LESS: d3dComp = D3DCMP_LESS; break;
105 case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
106 case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
107 case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
108 case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
109 case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
110 default: UNREACHABLE();
111 }
112
113 return d3dComp;
114}
115
116D3DCOLOR ConvertColor(gl::Color color)
117{
118 return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119 gl::unorm<8>(color.green),
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000120 gl::unorm<8>(color.blue),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121 gl::unorm<8>(color.alpha));
122}
123
124D3DBLEND ConvertBlendFunc(GLenum blend)
125{
126 D3DBLEND d3dBlend = D3DBLEND_ZERO;
127
128 switch (blend)
129 {
130 case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
131 case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
132 case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
133 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
134 case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
135 case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
136 case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
137 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
138 case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
139 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
140 case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
141 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
142 case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
143 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
144 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
145 default: UNREACHABLE();
146 }
147
148 return d3dBlend;
149}
150
151D3DBLENDOP ConvertBlendOp(GLenum blendOp)
152{
153 D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
154
155 switch (blendOp)
156 {
157 case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
158 case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
159 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
160 default: UNREACHABLE();
161 }
162
163 return d3dBlendOp;
164}
165
166D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
167{
168 D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
169
170 switch (stencilOp)
171 {
172 case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
173 case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
174 case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
175 case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
176 case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
177 case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
178 case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
179 case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
180 default: UNREACHABLE();
181 }
182
183 return d3dStencilOp;
184}
185
186D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
187{
188 D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
189
190 switch (wrap)
191 {
192 case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
193 case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
194 case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
195 default: UNREACHABLE();
196 }
197
198 return d3dWrap;
199}
200
201D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
202{
203 D3DCULL cull = D3DCULL_CCW;
204 switch (cullFace)
205 {
206 case GL_FRONT:
207 cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
208 break;
209 case GL_BACK:
210 cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
211 break;
212 case GL_FRONT_AND_BACK:
daniel@transgaming.comace5e662010-03-21 04:31:20 +0000213 cull = D3DCULL_NONE; // culling will be handled during draw
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000214 break;
215 default: UNREACHABLE();
216 }
217
218 return cull;
219}
220
221DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
222{
223 return (red ? D3DCOLORWRITEENABLE_RED : 0) |
224 (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
225 (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
226 (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
227}
228
229D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
230{
231 D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
232 switch (magFilter)
233 {
234 case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
235 case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
236 default: UNREACHABLE();
237 }
238
239 return d3dMagFilter;
240}
241
242void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
243{
244 switch (minFilter)
245 {
246 case GL_NEAREST:
247 *d3dMinFilter = D3DTEXF_POINT;
248 *d3dMipFilter = D3DTEXF_NONE;
249 break;
250 case GL_LINEAR:
251 *d3dMinFilter = D3DTEXF_LINEAR;
252 *d3dMipFilter = D3DTEXF_NONE;
253 break;
254 case GL_NEAREST_MIPMAP_NEAREST:
255 *d3dMinFilter = D3DTEXF_POINT;
256 *d3dMipFilter = D3DTEXF_POINT;
257 break;
258 case GL_LINEAR_MIPMAP_NEAREST:
259 *d3dMinFilter = D3DTEXF_LINEAR;
260 *d3dMipFilter = D3DTEXF_POINT;
261 break;
262 case GL_NEAREST_MIPMAP_LINEAR:
263 *d3dMinFilter = D3DTEXF_POINT;
264 *d3dMipFilter = D3DTEXF_LINEAR;
265 break;
266 case GL_LINEAR_MIPMAP_LINEAR:
267 *d3dMinFilter = D3DTEXF_LINEAR;
268 *d3dMipFilter = D3DTEXF_LINEAR;
269 break;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000270 default:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000271 *d3dMinFilter = D3DTEXF_POINT;
272 *d3dMipFilter = D3DTEXF_NONE;
273 UNREACHABLE();
274 }
275}
276
277unsigned int GetStencilSize(D3DFORMAT stencilFormat)
278{
279 switch(stencilFormat)
280 {
281 case D3DFMT_D24FS8:
282 case D3DFMT_D24S8:
283 return 8;
284 case D3DFMT_D24X4S4:
285 return 4;
286 case D3DFMT_D15S1:
287 return 1;
288 case D3DFMT_D16_LOCKABLE:
289 case D3DFMT_D32:
290 case D3DFMT_D24X8:
291 case D3DFMT_D32F_LOCKABLE:
292 case D3DFMT_D16:
293 return 0;
294// case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
295// case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
296 default: UNREACHABLE();
297 }
298 return 0;
299}
300
301unsigned int GetAlphaSize(D3DFORMAT colorFormat)
302{
303 switch (colorFormat)
304 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000305 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000306 return 2;
307 case D3DFMT_A8R8G8B8:
308 return 8;
309 case D3DFMT_A1R5G5B5:
310 return 1;
311 case D3DFMT_X8R8G8B8:
312 case D3DFMT_X1R5G5B5:
313 case D3DFMT_R5G6B5:
314 return 0;
315 default: UNREACHABLE();
316 }
317 return 0;
318}
319
320unsigned int GetRedSize(D3DFORMAT colorFormat)
321{
322 switch (colorFormat)
323 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000324 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000325 return 10;
326 case D3DFMT_A8R8G8B8:
327 case D3DFMT_X8R8G8B8:
328 return 8;
329 case D3DFMT_A1R5G5B5:
330 case D3DFMT_R5G6B5:
331 case D3DFMT_X1R5G5B5:
332 return 5;
333 default: UNREACHABLE();
334 }
335 return 0;
336}
337
338unsigned int GetGreenSize(D3DFORMAT colorFormat)
339{
340 switch (colorFormat)
341 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000342 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000343 return 10;
344 case D3DFMT_A8R8G8B8:
345 case D3DFMT_X8R8G8B8:
346 return 8;
347 case D3DFMT_A1R5G5B5:
348 case D3DFMT_X1R5G5B5:
349 return 5;
350 case D3DFMT_R5G6B5:
351 return 6;
352 default: UNREACHABLE();
353 }
354 return 0;
355}
356
357unsigned int GetBlueSize(D3DFORMAT colorFormat)
358{
359 switch (colorFormat)
360 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000361 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000362 return 10;
363 case D3DFMT_A8R8G8B8:
364 case D3DFMT_X8R8G8B8:
365 return 8;
366 case D3DFMT_A1R5G5B5:
367 case D3DFMT_R5G6B5:
368 case D3DFMT_X1R5G5B5:
369 return 5;
370 default: UNREACHABLE();
371 }
372 return 0;
373}
374
375unsigned int GetDepthSize(D3DFORMAT depthFormat)
376{
377 switch (depthFormat)
378 {
379 case D3DFMT_D16_LOCKABLE: return 16;
380 case D3DFMT_D32: return 32;
381 case D3DFMT_D15S1: return 15;
382 case D3DFMT_D24S8: return 24;
383 case D3DFMT_D24X8: return 24;
384 case D3DFMT_D24X4S4: return 24;
385 case D3DFMT_D16: return 16;
386 case D3DFMT_D32F_LOCKABLE: return 32;
387 case D3DFMT_D24FS8: return 24;
388// case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
389// case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
390 default:
391 UNREACHABLE();
392 }
393 return 0;
394}
395
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000396bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000397 D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
398{
399 switch (primitiveType)
400 {
401 case GL_POINTS:
402 *d3dPrimitiveType = D3DPT_POINTLIST;
403 *d3dPrimitiveCount = primitiveCount;
404 break;
405 case GL_LINES:
406 *d3dPrimitiveType = D3DPT_LINELIST;
407 *d3dPrimitiveCount = primitiveCount / 2;
408 break;
409 case GL_LINE_LOOP:
daniel@transgaming.combf2b52a2010-04-20 18:53:03 +0000410 *d3dPrimitiveType = D3DPT_LINESTRIP;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000411 *d3dPrimitiveCount = primitiveCount;
412 break;
413 case GL_LINE_STRIP:
414 *d3dPrimitiveType = D3DPT_LINESTRIP;
415 *d3dPrimitiveCount = primitiveCount - 1;
416 break;
417 case GL_TRIANGLES:
418 *d3dPrimitiveType = D3DPT_TRIANGLELIST;
419 *d3dPrimitiveCount = primitiveCount / 3;
420 break;
421 case GL_TRIANGLE_STRIP:
422 *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
423 *d3dPrimitiveCount = primitiveCount - 2;
424 break;
425 case GL_TRIANGLE_FAN:
426 *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
427 *d3dPrimitiveCount = primitiveCount - 2;
428 break;
429 default:
430 return false;
431 }
432
433 return true;
434}
435
daniel@transgaming.com00c75962010-03-11 20:36:15 +0000436bool IsCubemapTextureTarget(GLenum target)
437{
438 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
439}
440
441// Verify that format/type are one of the combinations from table 3.4.
442bool CheckTextureFormatType(GLenum format, GLenum type)
443{
444 switch (type)
445 {
446 case GL_UNSIGNED_BYTE:
447 switch (format)
448 {
449 case GL_RGBA:
450 case GL_RGB:
451 case GL_ALPHA:
452 case GL_LUMINANCE:
453 case GL_LUMINANCE_ALPHA:
454 return true;
455
456 default:
457 return false;
458 }
459
460 case GL_UNSIGNED_SHORT_4_4_4_4:
461 case GL_UNSIGNED_SHORT_5_5_5_1:
462 return (format == GL_RGBA);
463
464 case GL_UNSIGNED_SHORT_5_6_5:
465 return (format == GL_RGB);
466
467 default:
468 return false;
469 }
470}
471
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000472D3DFORMAT ConvertRenderbufferFormat(GLenum format)
473{
474 switch (format)
475 {
476 case GL_RGBA4:
477 case GL_RGB5_A1: return D3DFMT_A8R8G8B8;
478 case GL_RGB565: return D3DFMT_R5G6B5;
479 case GL_DEPTH_COMPONENT16:
480 case GL_STENCIL_INDEX8: return D3DFMT_D24S8;
481 default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
482 }
483}
484
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000485}