blob: a7cbc0f1b5bbdff5039c1ac6d5bf89b4dd6733d4 [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
9#include "utilities.h"
10
11#include "debug.h"
12#include "mathutil.h"
13#include "Context.h"
14
15namespace es2dx
16{
17
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000018D3DCMPFUNC ConvertComparison(GLenum comparison)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000019{
20 D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
21 switch (comparison)
22 {
23 case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
24 case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
25 case GL_LESS: d3dComp = D3DCMP_LESS; break;
26 case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
27 case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
28 case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
29 case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
30 case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
31 default: UNREACHABLE();
32 }
33
34 return d3dComp;
35}
36
37D3DCOLOR ConvertColor(gl::Color color)
38{
39 return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000040 gl::unorm<8>(color.green),
daniel@transgaming.comfe453652010-03-16 06:23:28 +000041 gl::unorm<8>(color.blue),
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000042 gl::unorm<8>(color.alpha));
43}
44
45D3DBLEND ConvertBlendFunc(GLenum blend)
46{
47 D3DBLEND d3dBlend = D3DBLEND_ZERO;
48
49 switch (blend)
50 {
51 case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
52 case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
53 case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
54 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
55 case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
56 case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
57 case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
58 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
59 case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
60 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
61 case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
62 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
63 case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
64 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
65 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
66 default: UNREACHABLE();
67 }
68
69 return d3dBlend;
70}
71
72D3DBLENDOP ConvertBlendOp(GLenum blendOp)
73{
74 D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
75
76 switch (blendOp)
77 {
78 case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
79 case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
80 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
81 default: UNREACHABLE();
82 }
83
84 return d3dBlendOp;
85}
86
87D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
88{
89 D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
90
91 switch (stencilOp)
92 {
93 case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
94 case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
95 case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
96 case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
97 case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
98 case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
99 case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
100 case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
101 default: UNREACHABLE();
102 }
103
104 return d3dStencilOp;
105}
106
107D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
108{
109 D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
110
111 switch (wrap)
112 {
113 case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
114 case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
115 case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
116 default: UNREACHABLE();
117 }
118
119 return d3dWrap;
120}
121
122D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
123{
124 D3DCULL cull = D3DCULL_CCW;
125 switch (cullFace)
126 {
127 case GL_FRONT:
128 cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
129 break;
130 case GL_BACK:
131 cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
132 break;
133 case GL_FRONT_AND_BACK:
daniel@transgaming.comace5e662010-03-21 04:31:20 +0000134 cull = D3DCULL_NONE; // culling will be handled during draw
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135 break;
136 default: UNREACHABLE();
137 }
138
139 return cull;
140}
141
142DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
143{
144 return (red ? D3DCOLORWRITEENABLE_RED : 0) |
145 (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
146 (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
147 (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
148}
149
150D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
151{
152 D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
153 switch (magFilter)
154 {
155 case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
156 case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
157 default: UNREACHABLE();
158 }
159
160 return d3dMagFilter;
161}
162
163void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
164{
165 switch (minFilter)
166 {
167 case GL_NEAREST:
168 *d3dMinFilter = D3DTEXF_POINT;
169 *d3dMipFilter = D3DTEXF_NONE;
170 break;
171 case GL_LINEAR:
172 *d3dMinFilter = D3DTEXF_LINEAR;
173 *d3dMipFilter = D3DTEXF_NONE;
174 break;
175 case GL_NEAREST_MIPMAP_NEAREST:
176 *d3dMinFilter = D3DTEXF_POINT;
177 *d3dMipFilter = D3DTEXF_POINT;
178 break;
179 case GL_LINEAR_MIPMAP_NEAREST:
180 *d3dMinFilter = D3DTEXF_LINEAR;
181 *d3dMipFilter = D3DTEXF_POINT;
182 break;
183 case GL_NEAREST_MIPMAP_LINEAR:
184 *d3dMinFilter = D3DTEXF_POINT;
185 *d3dMipFilter = D3DTEXF_LINEAR;
186 break;
187 case GL_LINEAR_MIPMAP_LINEAR:
188 *d3dMinFilter = D3DTEXF_LINEAR;
189 *d3dMipFilter = D3DTEXF_LINEAR;
190 break;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000191 default:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000192 *d3dMinFilter = D3DTEXF_POINT;
193 *d3dMipFilter = D3DTEXF_NONE;
194 UNREACHABLE();
195 }
196}
197
198unsigned int GetStencilSize(D3DFORMAT stencilFormat)
199{
200 switch(stencilFormat)
201 {
202 case D3DFMT_D24FS8:
203 case D3DFMT_D24S8:
204 return 8;
205 case D3DFMT_D24X4S4:
206 return 4;
207 case D3DFMT_D15S1:
208 return 1;
209 case D3DFMT_D16_LOCKABLE:
210 case D3DFMT_D32:
211 case D3DFMT_D24X8:
212 case D3DFMT_D32F_LOCKABLE:
213 case D3DFMT_D16:
214 return 0;
215// case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
216// case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
217 default: UNREACHABLE();
218 }
219 return 0;
220}
221
222unsigned int GetAlphaSize(D3DFORMAT colorFormat)
223{
224 switch (colorFormat)
225 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000226 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227 return 2;
228 case D3DFMT_A8R8G8B8:
229 return 8;
230 case D3DFMT_A1R5G5B5:
231 return 1;
232 case D3DFMT_X8R8G8B8:
233 case D3DFMT_X1R5G5B5:
234 case D3DFMT_R5G6B5:
235 return 0;
236 default: UNREACHABLE();
237 }
238 return 0;
239}
240
241unsigned int GetRedSize(D3DFORMAT colorFormat)
242{
243 switch (colorFormat)
244 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000245 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000246 return 10;
247 case D3DFMT_A8R8G8B8:
248 case D3DFMT_X8R8G8B8:
249 return 8;
250 case D3DFMT_A1R5G5B5:
251 case D3DFMT_R5G6B5:
252 case D3DFMT_X1R5G5B5:
253 return 5;
254 default: UNREACHABLE();
255 }
256 return 0;
257}
258
259unsigned int GetGreenSize(D3DFORMAT colorFormat)
260{
261 switch (colorFormat)
262 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000263 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264 return 10;
265 case D3DFMT_A8R8G8B8:
266 case D3DFMT_X8R8G8B8:
267 return 8;
268 case D3DFMT_A1R5G5B5:
269 case D3DFMT_X1R5G5B5:
270 return 5;
271 case D3DFMT_R5G6B5:
272 return 6;
273 default: UNREACHABLE();
274 }
275 return 0;
276}
277
278unsigned int GetBlueSize(D3DFORMAT colorFormat)
279{
280 switch (colorFormat)
281 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000282 case D3DFMT_A2R10G10B10:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000283 return 10;
284 case D3DFMT_A8R8G8B8:
285 case D3DFMT_X8R8G8B8:
286 return 8;
287 case D3DFMT_A1R5G5B5:
288 case D3DFMT_R5G6B5:
289 case D3DFMT_X1R5G5B5:
290 return 5;
291 default: UNREACHABLE();
292 }
293 return 0;
294}
295
296unsigned int GetDepthSize(D3DFORMAT depthFormat)
297{
298 switch (depthFormat)
299 {
300 case D3DFMT_D16_LOCKABLE: return 16;
301 case D3DFMT_D32: return 32;
302 case D3DFMT_D15S1: return 15;
303 case D3DFMT_D24S8: return 24;
304 case D3DFMT_D24X8: return 24;
305 case D3DFMT_D24X4S4: return 24;
306 case D3DFMT_D16: return 16;
307 case D3DFMT_D32F_LOCKABLE: return 32;
308 case D3DFMT_D24FS8: return 24;
309// case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
310// case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
311 default:
312 UNREACHABLE();
313 }
314 return 0;
315}
316
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000317bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000318 D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
319{
320 switch (primitiveType)
321 {
322 case GL_POINTS:
323 *d3dPrimitiveType = D3DPT_POINTLIST;
324 *d3dPrimitiveCount = primitiveCount;
325 break;
326 case GL_LINES:
327 *d3dPrimitiveType = D3DPT_LINELIST;
328 *d3dPrimitiveCount = primitiveCount / 2;
329 break;
330 case GL_LINE_LOOP:
331 UNIMPLEMENTED(); // FIXME: Emulate using an index buffer
332 *d3dPrimitiveType = D3DPT_LINELIST;
333 *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.com4f39fd92010-03-08 20:26:45 +0000394}