• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
7 
8 // renderer9_utils.cpp: Conversion functions and other utility routines
9 // specific to the D3D9 renderer.
10 
11 #include "libGLESv2/renderer/renderer9_utils.h"
12 #include "libGLESv2/mathutil.h"
13 #include "libGLESv2/Context.h"
14 
15 #include "common/debug.h"
16 
17 namespace gl_d3d9
18 {
19 
ConvertComparison(GLenum comparison)20 D3DCMPFUNC ConvertComparison(GLenum comparison)
21 {
22     D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
23     switch (comparison)
24     {
25       case GL_NEVER:    d3dComp = D3DCMP_NEVER;        break;
26       case GL_ALWAYS:   d3dComp = D3DCMP_ALWAYS;       break;
27       case GL_LESS:     d3dComp = D3DCMP_LESS;         break;
28       case GL_LEQUAL:   d3dComp = D3DCMP_LESSEQUAL;    break;
29       case GL_EQUAL:    d3dComp = D3DCMP_EQUAL;        break;
30       case GL_GREATER:  d3dComp = D3DCMP_GREATER;      break;
31       case GL_GEQUAL:   d3dComp = D3DCMP_GREATEREQUAL; break;
32       case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL;     break;
33       default: UNREACHABLE();
34     }
35 
36     return d3dComp;
37 }
38 
ConvertColor(gl::Color color)39 D3DCOLOR ConvertColor(gl::Color color)
40 {
41     return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
42                          gl::unorm<8>(color.green),
43                          gl::unorm<8>(color.blue),
44                          gl::unorm<8>(color.alpha));
45 }
46 
ConvertBlendFunc(GLenum blend)47 D3DBLEND ConvertBlendFunc(GLenum blend)
48 {
49     D3DBLEND d3dBlend = D3DBLEND_ZERO;
50 
51     switch (blend)
52     {
53       case GL_ZERO:                     d3dBlend = D3DBLEND_ZERO;           break;
54       case GL_ONE:                      d3dBlend = D3DBLEND_ONE;            break;
55       case GL_SRC_COLOR:                d3dBlend = D3DBLEND_SRCCOLOR;       break;
56       case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = D3DBLEND_INVSRCCOLOR;    break;
57       case GL_DST_COLOR:                d3dBlend = D3DBLEND_DESTCOLOR;      break;
58       case GL_ONE_MINUS_DST_COLOR:      d3dBlend = D3DBLEND_INVDESTCOLOR;   break;
59       case GL_SRC_ALPHA:                d3dBlend = D3DBLEND_SRCALPHA;       break;
60       case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3DBLEND_INVSRCALPHA;    break;
61       case GL_DST_ALPHA:                d3dBlend = D3DBLEND_DESTALPHA;      break;
62       case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3DBLEND_INVDESTALPHA;   break;
63       case GL_CONSTANT_COLOR:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
64       case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
65       case GL_CONSTANT_ALPHA:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
66       case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
67       case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3DBLEND_SRCALPHASAT;    break;
68       default: UNREACHABLE();
69     }
70 
71     return d3dBlend;
72 }
73 
ConvertBlendOp(GLenum blendOp)74 D3DBLENDOP ConvertBlendOp(GLenum blendOp)
75 {
76     D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
77 
78     switch (blendOp)
79     {
80       case GL_FUNC_ADD:              d3dBlendOp = D3DBLENDOP_ADD;         break;
81       case GL_FUNC_SUBTRACT:         d3dBlendOp = D3DBLENDOP_SUBTRACT;    break;
82       case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
83       default: UNREACHABLE();
84     }
85 
86     return d3dBlendOp;
87 }
88 
ConvertStencilOp(GLenum stencilOp)89 D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
90 {
91     D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
92 
93     switch (stencilOp)
94     {
95       case GL_ZERO:      d3dStencilOp = D3DSTENCILOP_ZERO;    break;
96       case GL_KEEP:      d3dStencilOp = D3DSTENCILOP_KEEP;    break;
97       case GL_REPLACE:   d3dStencilOp = D3DSTENCILOP_REPLACE; break;
98       case GL_INCR:      d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
99       case GL_DECR:      d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
100       case GL_INVERT:    d3dStencilOp = D3DSTENCILOP_INVERT;  break;
101       case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR;    break;
102       case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR;    break;
103       default: UNREACHABLE();
104     }
105 
106     return d3dStencilOp;
107 }
108 
ConvertTextureWrap(GLenum wrap)109 D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
110 {
111     D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
112 
113     switch (wrap)
114     {
115       case GL_REPEAT:            d3dWrap = D3DTADDRESS_WRAP;   break;
116       case GL_CLAMP_TO_EDGE:     d3dWrap = D3DTADDRESS_CLAMP;  break;
117       case GL_MIRRORED_REPEAT:   d3dWrap = D3DTADDRESS_MIRROR; break;
118       default: UNREACHABLE();
119     }
120 
121     return d3dWrap;
122 }
123 
ConvertCullMode(GLenum cullFace,GLenum frontFace)124 D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
125 {
126     D3DCULL cull = D3DCULL_CCW;
127     switch (cullFace)
128     {
129       case GL_FRONT:
130         cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
131         break;
132       case GL_BACK:
133         cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
134         break;
135       case GL_FRONT_AND_BACK:
136         cull = D3DCULL_NONE; // culling will be handled during draw
137         break;
138       default: UNREACHABLE();
139     }
140 
141     return cull;
142 }
143 
ConvertCubeFace(GLenum cubeFace)144 D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
145 {
146     D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
147 
148     switch (cubeFace)
149     {
150       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
151         face = D3DCUBEMAP_FACE_POSITIVE_X;
152         break;
153       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
154         face = D3DCUBEMAP_FACE_NEGATIVE_X;
155         break;
156       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
157         face = D3DCUBEMAP_FACE_POSITIVE_Y;
158         break;
159       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
160         face = D3DCUBEMAP_FACE_NEGATIVE_Y;
161         break;
162       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
163         face = D3DCUBEMAP_FACE_POSITIVE_Z;
164         break;
165       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
166         face = D3DCUBEMAP_FACE_NEGATIVE_Z;
167         break;
168       default: UNREACHABLE();
169     }
170 
171     return face;
172 }
173 
ConvertColorMask(bool red,bool green,bool blue,bool alpha)174 DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
175 {
176     return (red   ? D3DCOLORWRITEENABLE_RED   : 0) |
177            (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
178            (blue  ? D3DCOLORWRITEENABLE_BLUE  : 0) |
179            (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
180 }
181 
ConvertMagFilter(GLenum magFilter,float maxAnisotropy)182 D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
183 {
184     if (maxAnisotropy > 1.0f)
185     {
186         return D3DTEXF_ANISOTROPIC;
187     }
188 
189     D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
190     switch (magFilter)
191     {
192       case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT;  break;
193       case GL_LINEAR:  d3dMagFilter = D3DTEXF_LINEAR; break;
194       default: UNREACHABLE();
195     }
196 
197     return d3dMagFilter;
198 }
199 
ConvertMinFilter(GLenum minFilter,D3DTEXTUREFILTERTYPE * d3dMinFilter,D3DTEXTUREFILTERTYPE * d3dMipFilter,float maxAnisotropy)200 void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
201 {
202     switch (minFilter)
203     {
204       case GL_NEAREST:
205         *d3dMinFilter = D3DTEXF_POINT;
206         *d3dMipFilter = D3DTEXF_NONE;
207         break;
208       case GL_LINEAR:
209         *d3dMinFilter = D3DTEXF_LINEAR;
210         *d3dMipFilter = D3DTEXF_NONE;
211         break;
212       case GL_NEAREST_MIPMAP_NEAREST:
213         *d3dMinFilter = D3DTEXF_POINT;
214         *d3dMipFilter = D3DTEXF_POINT;
215         break;
216       case GL_LINEAR_MIPMAP_NEAREST:
217         *d3dMinFilter = D3DTEXF_LINEAR;
218         *d3dMipFilter = D3DTEXF_POINT;
219         break;
220       case GL_NEAREST_MIPMAP_LINEAR:
221         *d3dMinFilter = D3DTEXF_POINT;
222         *d3dMipFilter = D3DTEXF_LINEAR;
223         break;
224       case GL_LINEAR_MIPMAP_LINEAR:
225         *d3dMinFilter = D3DTEXF_LINEAR;
226         *d3dMipFilter = D3DTEXF_LINEAR;
227         break;
228       default:
229         *d3dMinFilter = D3DTEXF_POINT;
230         *d3dMipFilter = D3DTEXF_NONE;
231         UNREACHABLE();
232     }
233 
234     if (maxAnisotropy > 1.0f)
235     {
236         *d3dMinFilter = D3DTEXF_ANISOTROPIC;
237     }
238 }
239 
ConvertRenderbufferFormat(GLenum format)240 D3DFORMAT ConvertRenderbufferFormat(GLenum format)
241 {
242     switch (format)
243     {
244       case GL_NONE:                 return D3DFMT_NULL;
245       case GL_RGBA4:
246       case GL_RGB5_A1:
247       case GL_RGBA8_OES:            return D3DFMT_A8R8G8B8;
248       case GL_RGB565:               return D3DFMT_R5G6B5;
249       case GL_RGB8_OES:             return D3DFMT_X8R8G8B8;
250       case GL_DEPTH_COMPONENT16:
251       case GL_STENCIL_INDEX8:
252       case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
253       default: UNREACHABLE();       return D3DFMT_A8R8G8B8;
254     }
255 }
256 
GetMultisampleTypeFromSamples(GLsizei samples)257 D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
258 {
259     if (samples <= 1)
260         return D3DMULTISAMPLE_NONE;
261     else
262         return (D3DMULTISAMPLE_TYPE)samples;
263 }
264 
265 }
266 
267 namespace d3d9_gl
268 {
269 
GetStencilSize(D3DFORMAT stencilFormat)270 unsigned int GetStencilSize(D3DFORMAT stencilFormat)
271 {
272     if (stencilFormat == D3DFMT_INTZ)
273     {
274         return 8;
275     }
276     switch(stencilFormat)
277     {
278       case D3DFMT_D24FS8:
279       case D3DFMT_D24S8:
280         return 8;
281       case D3DFMT_D24X4S4:
282         return 4;
283       case D3DFMT_D15S1:
284         return 1;
285       case D3DFMT_D16_LOCKABLE:
286       case D3DFMT_D32:
287       case D3DFMT_D24X8:
288       case D3DFMT_D32F_LOCKABLE:
289       case D3DFMT_D16:
290         return 0;
291     //case D3DFMT_D32_LOCKABLE:  return 0;   // DirectX 9Ex only
292     //case D3DFMT_S8_LOCKABLE:   return 8;   // DirectX 9Ex only
293       default:
294         return 0;
295     }
296 }
297 
GetAlphaSize(D3DFORMAT colorFormat)298 unsigned int GetAlphaSize(D3DFORMAT colorFormat)
299 {
300     switch (colorFormat)
301     {
302       case D3DFMT_A16B16G16R16F:
303         return 16;
304       case D3DFMT_A32B32G32R32F:
305         return 32;
306       case D3DFMT_A2R10G10B10:
307         return 2;
308       case D3DFMT_A8R8G8B8:
309         return 8;
310       case D3DFMT_A1R5G5B5:
311         return 1;
312       case D3DFMT_X8R8G8B8:
313       case D3DFMT_R5G6B5:
314         return 0;
315       default:
316         return 0;
317     }
318 }
319 
GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)320 GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
321 {
322     if (type == D3DMULTISAMPLE_NONMASKABLE)
323         return 0;
324     else
325         return type;
326 }
327 
IsFormatChannelEquivalent(D3DFORMAT d3dformat,GLenum format)328 bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
329 {
330     switch (d3dformat)
331     {
332       case D3DFMT_L8:
333         return (format == GL_LUMINANCE);
334       case D3DFMT_A8L8:
335         return (format == GL_LUMINANCE_ALPHA);
336       case D3DFMT_DXT1:
337         return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
338       case D3DFMT_DXT3:
339         return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
340       case D3DFMT_DXT5:
341         return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
342       case D3DFMT_A8R8G8B8:
343       case D3DFMT_A16B16G16R16F:
344       case D3DFMT_A32B32G32R32F:
345         return (format == GL_RGBA || format == GL_BGRA_EXT);
346       case D3DFMT_X8R8G8B8:
347         return (format == GL_RGB);
348       default:
349         if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format))
350             return true;
351         return false;
352     }
353 }
354 
ConvertBackBufferFormat(D3DFORMAT format)355 GLenum ConvertBackBufferFormat(D3DFORMAT format)
356 {
357     switch (format)
358     {
359       case D3DFMT_A4R4G4B4: return GL_RGBA4;
360       case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
361       case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
362       case D3DFMT_R5G6B5:   return GL_RGB565;
363       case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
364       default:
365         UNREACHABLE();
366     }
367 
368     return GL_RGBA4;
369 }
370 
ConvertDepthStencilFormat(D3DFORMAT format)371 GLenum ConvertDepthStencilFormat(D3DFORMAT format)
372 {
373     if (format == D3DFMT_INTZ)
374     {
375         return GL_DEPTH24_STENCIL8_OES;
376     }
377     switch (format)
378     {
379       case D3DFMT_D16:
380       case D3DFMT_D24X8:
381         return GL_DEPTH_COMPONENT16;
382       case D3DFMT_D24S8:
383         return GL_DEPTH24_STENCIL8_OES;
384       case D3DFMT_UNKNOWN:
385         return GL_NONE;
386       default:
387         UNREACHABLE();
388     }
389 
390     return GL_DEPTH24_STENCIL8_OES;
391 }
392 
ConvertRenderTargetFormat(D3DFORMAT format)393 GLenum ConvertRenderTargetFormat(D3DFORMAT format)
394 {
395     if (format == D3DFMT_INTZ)
396     {
397         return GL_DEPTH24_STENCIL8_OES;
398     }
399 
400     switch (format)
401     {
402       case D3DFMT_A4R4G4B4: return GL_RGBA4;
403       case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
404       case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
405       case D3DFMT_R5G6B5:   return GL_RGB565;
406       case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
407       case D3DFMT_D16:
408       case D3DFMT_D24X8:
409         return GL_DEPTH_COMPONENT16;
410       case D3DFMT_D24S8:
411         return GL_DEPTH24_STENCIL8_OES;
412       case D3DFMT_UNKNOWN:
413         return GL_NONE;
414       default:
415         UNREACHABLE();
416     }
417 
418     return GL_RGBA4;
419 }
420 
GetEquivalentFormat(D3DFORMAT format)421 GLenum GetEquivalentFormat(D3DFORMAT format)
422 {
423     if (format == D3DFMT_INTZ)
424         return GL_DEPTH24_STENCIL8_OES;
425     if (format == D3DFMT_NULL)
426         return GL_NONE;
427 
428     switch (format)
429     {
430       case D3DFMT_A4R4G4B4:             return GL_RGBA4;
431       case D3DFMT_A8R8G8B8:             return GL_RGBA8_OES;
432       case D3DFMT_A1R5G5B5:             return GL_RGB5_A1;
433       case D3DFMT_R5G6B5:               return GL_RGB565;
434       case D3DFMT_X8R8G8B8:             return GL_RGB8_OES;
435       case D3DFMT_D16:                  return GL_DEPTH_COMPONENT16;
436       case D3DFMT_D24S8:                return GL_DEPTH24_STENCIL8_OES;
437       case D3DFMT_UNKNOWN:              return GL_NONE;
438       case D3DFMT_DXT1:                 return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
439       case D3DFMT_DXT3:                 return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
440       case D3DFMT_DXT5:                 return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
441       case D3DFMT_A32B32G32R32F:        return GL_RGBA32F_EXT;
442       case D3DFMT_A16B16G16R16F:        return GL_RGBA16F_EXT;
443       case D3DFMT_L8:                   return GL_LUMINANCE8_EXT;
444       case D3DFMT_A8L8:                 return GL_LUMINANCE8_ALPHA8_EXT;
445       default:              UNREACHABLE();
446         return GL_NONE;
447     }
448 }
449 
450 }
451 
452 namespace d3d9
453 {
454 
IsCompressedFormat(D3DFORMAT surfaceFormat)455 bool IsCompressedFormat(D3DFORMAT surfaceFormat)
456 {
457     switch(surfaceFormat)
458     {
459       case D3DFMT_DXT1:
460       case D3DFMT_DXT2:
461       case D3DFMT_DXT3:
462       case D3DFMT_DXT4:
463       case D3DFMT_DXT5:
464         return true;
465       default:
466         return false;
467     }
468 }
469 
ComputeRowSize(D3DFORMAT format,unsigned int width)470 size_t ComputeRowSize(D3DFORMAT format, unsigned int width)
471 {
472     if (format == D3DFMT_INTZ)
473     {
474         return 4 * width;
475     }
476     switch (format)
477     {
478       case D3DFMT_L8:
479           return 1 * width;
480       case D3DFMT_A8L8:
481           return 2 * width;
482       case D3DFMT_X8R8G8B8:
483       case D3DFMT_A8R8G8B8:
484         return 4 * width;
485       case D3DFMT_A16B16G16R16F:
486         return 8 * width;
487       case D3DFMT_A32B32G32R32F:
488         return 16 * width;
489       case D3DFMT_DXT1:
490         return 8 * ((width + 3) / 4);
491       case D3DFMT_DXT3:
492       case D3DFMT_DXT5:
493         return 16 * ((width + 3) / 4);
494       default:
495         UNREACHABLE();
496         return 0;
497     }
498 }
499 
500 }
501