blob: 92e819cbc65783fa4acf4c21132640f7bcf3d864 [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
16namespace es2dx
17{
18
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000019D3DCMPFUNC ConvertComparison(GLenum comparison)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020{
21 D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
22 switch (comparison)
23 {
24 case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
25 case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
26 case GL_LESS: d3dComp = D3DCMP_LESS; break;
27 case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
28 case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
29 case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
30 case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
31 case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
32 default: UNREACHABLE();
33 }
34
35 return d3dComp;
36}
37
38D3DCOLOR ConvertColor(gl::Color color)
39{
40 return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000041 gl::unorm<8>(color.green),
daniel@transgaming.comfe453652010-03-16 06:23:28 +000042 gl::unorm<8>(color.blue),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000043 gl::unorm<8>(color.alpha));
44}
45
46D3DBLEND ConvertBlendFunc(GLenum blend)
47{
48 D3DBLEND d3dBlend = D3DBLEND_ZERO;
49
50 switch (blend)
51 {
52 case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
53 case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
54 case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
55 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
56 case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
57 case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
58 case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
59 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
60 case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
61 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
62 case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
63 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
64 case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
65 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
66 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
67 default: UNREACHABLE();
68 }
69
70 return d3dBlend;
71}
72
73D3DBLENDOP ConvertBlendOp(GLenum blendOp)
74{
75 D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
76
77 switch (blendOp)
78 {
79 case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
80 case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
81 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
82 default: UNREACHABLE();
83 }
84
85 return d3dBlendOp;
86}
87
88D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
89{
90 D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
91
92 switch (stencilOp)
93 {
94 case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
95 case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
96 case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
97 case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
98 case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
99 case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
100 case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
101 case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
102 default: UNREACHABLE();
103 }
104
105 return d3dStencilOp;
106}
107
108D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
109{
110 D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
111
112 switch (wrap)
113 {
114 case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
115 case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
116 case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
117 default: UNREACHABLE();
118 }
119
120 return d3dWrap;
121}
122
123D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
124{
125 D3DCULL cull = D3DCULL_CCW;
126 switch (cullFace)
127 {
128 case GL_FRONT:
129 cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
130 break;
131 case GL_BACK:
132 cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
133 break;
134 case GL_FRONT_AND_BACK:
daniel@transgaming.comace5e662010-03-21 04:31:20 +0000135 cull = D3DCULL_NONE; // culling will be handled during draw
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000136 break;
137 default: UNREACHABLE();
138 }
139
140 return cull;
141}
142
143DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
144{
145 return (red ? D3DCOLORWRITEENABLE_RED : 0) |
146 (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
147 (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
148 (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
149}
150
151D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
152{
153 D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
154 switch (magFilter)
155 {
156 case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
157 case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
158 default: UNREACHABLE();
159 }
160
161 return d3dMagFilter;
162}
163
164void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
165{
166 switch (minFilter)
167 {
168 case GL_NEAREST:
169 *d3dMinFilter = D3DTEXF_POINT;
170 *d3dMipFilter = D3DTEXF_NONE;
171 break;
172 case GL_LINEAR:
173 *d3dMinFilter = D3DTEXF_LINEAR;
174 *d3dMipFilter = D3DTEXF_NONE;
175 break;
176 case GL_NEAREST_MIPMAP_NEAREST:
177 *d3dMinFilter = D3DTEXF_POINT;
178 *d3dMipFilter = D3DTEXF_POINT;
179 break;
180 case GL_LINEAR_MIPMAP_NEAREST:
181 *d3dMinFilter = D3DTEXF_LINEAR;
182 *d3dMipFilter = D3DTEXF_POINT;
183 break;
184 case GL_NEAREST_MIPMAP_LINEAR:
185 *d3dMinFilter = D3DTEXF_POINT;
186 *d3dMipFilter = D3DTEXF_LINEAR;
187 break;
188 case GL_LINEAR_MIPMAP_LINEAR:
189 *d3dMinFilter = D3DTEXF_LINEAR;
190 *d3dMipFilter = D3DTEXF_LINEAR;
191 break;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000192 default:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193 *d3dMinFilter = D3DTEXF_POINT;
194 *d3dMipFilter = D3DTEXF_NONE;
195 UNREACHABLE();
196 }
197}
198
199unsigned int GetStencilSize(D3DFORMAT stencilFormat)
200{
201 switch(stencilFormat)
202 {
203 case D3DFMT_D24FS8:
204 case D3DFMT_D24S8:
205 return 8;
206 case D3DFMT_D24X4S4:
207 return 4;
208 case D3DFMT_D15S1:
209 return 1;
210 case D3DFMT_D16_LOCKABLE:
211 case D3DFMT_D32:
212 case D3DFMT_D24X8:
213 case D3DFMT_D32F_LOCKABLE:
214 case D3DFMT_D16:
215 return 0;
216// case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
217// case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
218 default: UNREACHABLE();
219 }
220 return 0;
221}
222
223unsigned int GetAlphaSize(D3DFORMAT colorFormat)
224{
225 switch (colorFormat)
226 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000227 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 return 2;
229 case D3DFMT_A8R8G8B8:
230 return 8;
231 case D3DFMT_A1R5G5B5:
232 return 1;
233 case D3DFMT_X8R8G8B8:
234 case D3DFMT_X1R5G5B5:
235 case D3DFMT_R5G6B5:
236 return 0;
237 default: UNREACHABLE();
238 }
239 return 0;
240}
241
242unsigned int GetRedSize(D3DFORMAT colorFormat)
243{
244 switch (colorFormat)
245 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000246 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000247 return 10;
248 case D3DFMT_A8R8G8B8:
249 case D3DFMT_X8R8G8B8:
250 return 8;
251 case D3DFMT_A1R5G5B5:
252 case D3DFMT_R5G6B5:
253 case D3DFMT_X1R5G5B5:
254 return 5;
255 default: UNREACHABLE();
256 }
257 return 0;
258}
259
260unsigned int GetGreenSize(D3DFORMAT colorFormat)
261{
262 switch (colorFormat)
263 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000264 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265 return 10;
266 case D3DFMT_A8R8G8B8:
267 case D3DFMT_X8R8G8B8:
268 return 8;
269 case D3DFMT_A1R5G5B5:
270 case D3DFMT_X1R5G5B5:
271 return 5;
272 case D3DFMT_R5G6B5:
273 return 6;
274 default: UNREACHABLE();
275 }
276 return 0;
277}
278
279unsigned int GetBlueSize(D3DFORMAT colorFormat)
280{
281 switch (colorFormat)
282 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000283 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000284 return 10;
285 case D3DFMT_A8R8G8B8:
286 case D3DFMT_X8R8G8B8:
287 return 8;
288 case D3DFMT_A1R5G5B5:
289 case D3DFMT_R5G6B5:
290 case D3DFMT_X1R5G5B5:
291 return 5;
292 default: UNREACHABLE();
293 }
294 return 0;
295}
296
297unsigned int GetDepthSize(D3DFORMAT depthFormat)
298{
299 switch (depthFormat)
300 {
301 case D3DFMT_D16_LOCKABLE: return 16;
302 case D3DFMT_D32: return 32;
303 case D3DFMT_D15S1: return 15;
304 case D3DFMT_D24S8: return 24;
305 case D3DFMT_D24X8: return 24;
306 case D3DFMT_D24X4S4: return 24;
307 case D3DFMT_D16: return 16;
308 case D3DFMT_D32F_LOCKABLE: return 32;
309 case D3DFMT_D24FS8: return 24;
310// case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
311// case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
312 default:
313 UNREACHABLE();
314 }
315 return 0;
316}
317
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000318bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000319 D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
320{
321 switch (primitiveType)
322 {
323 case GL_POINTS:
324 *d3dPrimitiveType = D3DPT_POINTLIST;
325 *d3dPrimitiveCount = primitiveCount;
326 break;
327 case GL_LINES:
328 *d3dPrimitiveType = D3DPT_LINELIST;
329 *d3dPrimitiveCount = primitiveCount / 2;
330 break;
331 case GL_LINE_LOOP:
daniel@transgaming.combf2b52a2010-04-20 18:53:03 +0000332 *d3dPrimitiveType = D3DPT_LINESTRIP;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000333 *d3dPrimitiveCount = primitiveCount;
334 break;
335 case GL_LINE_STRIP:
336 *d3dPrimitiveType = D3DPT_LINESTRIP;
337 *d3dPrimitiveCount = primitiveCount - 1;
338 break;
339 case GL_TRIANGLES:
340 *d3dPrimitiveType = D3DPT_TRIANGLELIST;
341 *d3dPrimitiveCount = primitiveCount / 3;
342 break;
343 case GL_TRIANGLE_STRIP:
344 *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
345 *d3dPrimitiveCount = primitiveCount - 2;
346 break;
347 case GL_TRIANGLE_FAN:
348 *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
349 *d3dPrimitiveCount = primitiveCount - 2;
350 break;
351 default:
352 return false;
353 }
354
355 return true;
356}
357
daniel@transgaming.com00c75962010-03-11 20:36:15 +0000358bool IsCubemapTextureTarget(GLenum target)
359{
360 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
361}
362
363// Verify that format/type are one of the combinations from table 3.4.
364bool CheckTextureFormatType(GLenum format, GLenum type)
365{
366 switch (type)
367 {
368 case GL_UNSIGNED_BYTE:
369 switch (format)
370 {
371 case GL_RGBA:
372 case GL_RGB:
373 case GL_ALPHA:
374 case GL_LUMINANCE:
375 case GL_LUMINANCE_ALPHA:
376 return true;
377
378 default:
379 return false;
380 }
381
382 case GL_UNSIGNED_SHORT_4_4_4_4:
383 case GL_UNSIGNED_SHORT_5_5_5_1:
384 return (format == GL_RGBA);
385
386 case GL_UNSIGNED_SHORT_5_6_5:
387 return (format == GL_RGB);
388
389 default:
390 return false;
391 }
392}
393
daniel@transgaming.com70d312a2010-04-20 18:52:38 +0000394D3DFORMAT ConvertRenderbufferFormat(GLenum format)
395{
396 switch (format)
397 {
398 case GL_RGBA4:
399 case GL_RGB5_A1: return D3DFMT_A8R8G8B8;
400 case GL_RGB565: return D3DFMT_R5G6B5;
401 case GL_DEPTH_COMPONENT16:
402 case GL_STENCIL_INDEX8: return D3DFMT_D24S8;
403 default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
404 }
405}
406
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000407}