/src/3rdparty/webkit/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 827 lines · 728 code · 87 blank · 12 comment · 53 complexity · f15971bfa78dbcb28da5b6f51b7ed0b9 MD5 · raw file

  1. //
  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. // utilities.cpp: Conversion functions and other utility routines.
  7. #include "libGLESv2/utilities.h"
  8. #include <limits>
  9. #include "common/debug.h"
  10. #include "libGLESv2/mathutil.h"
  11. #include "libGLESv2/Context.h"
  12. namespace gl
  13. {
  14. int UniformComponentCount(GLenum type)
  15. {
  16. switch (type)
  17. {
  18. case GL_BOOL:
  19. case GL_FLOAT:
  20. case GL_INT:
  21. case GL_SAMPLER_2D:
  22. case GL_SAMPLER_CUBE:
  23. return 1;
  24. case GL_BOOL_VEC2:
  25. case GL_FLOAT_VEC2:
  26. case GL_INT_VEC2:
  27. return 2;
  28. case GL_INT_VEC3:
  29. case GL_FLOAT_VEC3:
  30. case GL_BOOL_VEC3:
  31. return 3;
  32. case GL_BOOL_VEC4:
  33. case GL_FLOAT_VEC4:
  34. case GL_INT_VEC4:
  35. case GL_FLOAT_MAT2:
  36. return 4;
  37. case GL_FLOAT_MAT3:
  38. return 9;
  39. case GL_FLOAT_MAT4:
  40. return 16;
  41. default:
  42. UNREACHABLE();
  43. }
  44. return 0;
  45. }
  46. GLenum UniformComponentType(GLenum type)
  47. {
  48. switch(type)
  49. {
  50. case GL_BOOL:
  51. case GL_BOOL_VEC2:
  52. case GL_BOOL_VEC3:
  53. case GL_BOOL_VEC4:
  54. return GL_BOOL;
  55. case GL_FLOAT:
  56. case GL_FLOAT_VEC2:
  57. case GL_FLOAT_VEC3:
  58. case GL_FLOAT_VEC4:
  59. case GL_FLOAT_MAT2:
  60. case GL_FLOAT_MAT3:
  61. case GL_FLOAT_MAT4:
  62. return GL_FLOAT;
  63. case GL_INT:
  64. case GL_SAMPLER_2D:
  65. case GL_SAMPLER_CUBE:
  66. case GL_INT_VEC2:
  67. case GL_INT_VEC3:
  68. case GL_INT_VEC4:
  69. return GL_INT;
  70. default:
  71. UNREACHABLE();
  72. }
  73. return GL_NONE;
  74. }
  75. size_t UniformTypeSize(GLenum type)
  76. {
  77. switch(type)
  78. {
  79. case GL_BOOL: return sizeof(GLboolean);
  80. case GL_FLOAT: return sizeof(GLfloat);
  81. case GL_INT: return sizeof(GLint);
  82. }
  83. return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
  84. }
  85. int VariableRowCount(GLenum type)
  86. {
  87. switch (type)
  88. {
  89. case GL_NONE:
  90. return 0;
  91. case GL_BOOL:
  92. case GL_FLOAT:
  93. case GL_INT:
  94. case GL_BOOL_VEC2:
  95. case GL_FLOAT_VEC2:
  96. case GL_INT_VEC2:
  97. case GL_INT_VEC3:
  98. case GL_FLOAT_VEC3:
  99. case GL_BOOL_VEC3:
  100. case GL_BOOL_VEC4:
  101. case GL_FLOAT_VEC4:
  102. case GL_INT_VEC4:
  103. return 1;
  104. case GL_FLOAT_MAT2:
  105. return 2;
  106. case GL_FLOAT_MAT3:
  107. return 3;
  108. case GL_FLOAT_MAT4:
  109. return 4;
  110. default:
  111. UNREACHABLE();
  112. }
  113. return 0;
  114. }
  115. int VariableColumnCount(GLenum type)
  116. {
  117. switch (type)
  118. {
  119. case GL_NONE:
  120. return 0;
  121. case GL_BOOL:
  122. case GL_FLOAT:
  123. case GL_INT:
  124. return 1;
  125. case GL_BOOL_VEC2:
  126. case GL_FLOAT_VEC2:
  127. case GL_INT_VEC2:
  128. case GL_FLOAT_MAT2:
  129. return 2;
  130. case GL_INT_VEC3:
  131. case GL_FLOAT_VEC3:
  132. case GL_BOOL_VEC3:
  133. case GL_FLOAT_MAT3:
  134. return 3;
  135. case GL_BOOL_VEC4:
  136. case GL_FLOAT_VEC4:
  137. case GL_INT_VEC4:
  138. case GL_FLOAT_MAT4:
  139. return 4;
  140. default:
  141. UNREACHABLE();
  142. }
  143. return 0;
  144. }
  145. int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
  146. {
  147. ASSERT(allocationSize <= bitsSize);
  148. unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
  149. for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
  150. {
  151. if ((*bits & mask) == 0)
  152. {
  153. *bits |= mask;
  154. return i;
  155. }
  156. mask <<= 1;
  157. }
  158. return -1;
  159. }
  160. GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
  161. {
  162. ASSERT(alignment > 0 && isPow2(alignment));
  163. GLsizei rawPitch = ComputePixelSize(format, type) * width;
  164. return (rawPitch + alignment - 1) & ~(alignment - 1);
  165. }
  166. GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
  167. {
  168. switch (format)
  169. {
  170. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  171. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  172. break;
  173. default:
  174. return 0;
  175. }
  176. ASSERT(width % 4 == 0);
  177. return 8 * width / 4;
  178. }
  179. GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
  180. {
  181. switch (format)
  182. {
  183. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  184. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  185. break;
  186. default:
  187. return 0;
  188. }
  189. return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
  190. }
  191. bool IsCompressed(GLenum format)
  192. {
  193. if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
  194. format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
  195. {
  196. return true;
  197. }
  198. else
  199. {
  200. return false;
  201. }
  202. }
  203. // Returns the size, in bytes, of a single texel in an Image
  204. int ComputePixelSize(GLenum format, GLenum type)
  205. {
  206. switch (type)
  207. {
  208. case GL_UNSIGNED_BYTE:
  209. switch (format)
  210. {
  211. case GL_ALPHA: return sizeof(unsigned char);
  212. case GL_LUMINANCE: return sizeof(unsigned char);
  213. case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
  214. case GL_RGB: return sizeof(unsigned char) * 3;
  215. case GL_RGBA: return sizeof(unsigned char) * 4;
  216. case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
  217. default: UNREACHABLE();
  218. }
  219. break;
  220. case GL_UNSIGNED_SHORT_4_4_4_4:
  221. case GL_UNSIGNED_SHORT_5_5_5_1:
  222. case GL_UNSIGNED_SHORT_5_6_5:
  223. return sizeof(unsigned short);
  224. case GL_FLOAT:
  225. switch (format)
  226. {
  227. case GL_ALPHA: return sizeof(float);
  228. case GL_LUMINANCE: return sizeof(float);
  229. case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
  230. case GL_RGB: return sizeof(float) * 3;
  231. case GL_RGBA: return sizeof(float) * 4;
  232. default: UNREACHABLE();
  233. }
  234. break;
  235. case GL_HALF_FLOAT_OES:
  236. switch (format)
  237. {
  238. case GL_ALPHA: return sizeof(unsigned short);
  239. case GL_LUMINANCE: return sizeof(unsigned short);
  240. case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
  241. case GL_RGB: return sizeof(unsigned short) * 3;
  242. case GL_RGBA: return sizeof(unsigned short) * 4;
  243. default: UNREACHABLE();
  244. }
  245. break;
  246. default: UNREACHABLE();
  247. }
  248. return 0;
  249. }
  250. bool IsCubemapTextureTarget(GLenum target)
  251. {
  252. return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
  253. }
  254. bool IsTextureTarget(GLenum target)
  255. {
  256. return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
  257. }
  258. // Verify that format/type are one of the combinations from table 3.4.
  259. bool CheckTextureFormatType(GLenum format, GLenum type)
  260. {
  261. switch (type)
  262. {
  263. case GL_UNSIGNED_BYTE:
  264. switch (format)
  265. {
  266. case GL_RGBA:
  267. case GL_BGRA_EXT:
  268. case GL_RGB:
  269. case GL_ALPHA:
  270. case GL_LUMINANCE:
  271. case GL_LUMINANCE_ALPHA:
  272. return true;
  273. default:
  274. return false;
  275. }
  276. case GL_FLOAT:
  277. case GL_HALF_FLOAT_OES:
  278. switch (format)
  279. {
  280. case GL_RGBA:
  281. case GL_RGB:
  282. case GL_ALPHA:
  283. case GL_LUMINANCE:
  284. case GL_LUMINANCE_ALPHA:
  285. return true;
  286. default:
  287. return false;
  288. }
  289. case GL_UNSIGNED_SHORT_4_4_4_4:
  290. case GL_UNSIGNED_SHORT_5_5_5_1:
  291. return (format == GL_RGBA);
  292. case GL_UNSIGNED_SHORT_5_6_5:
  293. return (format == GL_RGB);
  294. default:
  295. return false;
  296. }
  297. }
  298. bool IsColorRenderable(GLenum internalformat)
  299. {
  300. switch (internalformat)
  301. {
  302. case GL_RGBA4:
  303. case GL_RGB5_A1:
  304. case GL_RGB565:
  305. case GL_RGB8_OES:
  306. case GL_RGBA8_OES:
  307. return true;
  308. case GL_DEPTH_COMPONENT16:
  309. case GL_STENCIL_INDEX8:
  310. case GL_DEPTH24_STENCIL8_OES:
  311. return false;
  312. default:
  313. UNIMPLEMENTED();
  314. }
  315. return false;
  316. }
  317. bool IsDepthRenderable(GLenum internalformat)
  318. {
  319. switch (internalformat)
  320. {
  321. case GL_DEPTH_COMPONENT16:
  322. case GL_DEPTH24_STENCIL8_OES:
  323. return true;
  324. case GL_STENCIL_INDEX8:
  325. case GL_RGBA4:
  326. case GL_RGB5_A1:
  327. case GL_RGB565:
  328. case GL_RGB8_OES:
  329. case GL_RGBA8_OES:
  330. return false;
  331. default:
  332. UNIMPLEMENTED();
  333. }
  334. return false;
  335. }
  336. bool IsStencilRenderable(GLenum internalformat)
  337. {
  338. switch (internalformat)
  339. {
  340. case GL_STENCIL_INDEX8:
  341. case GL_DEPTH24_STENCIL8_OES:
  342. return true;
  343. case GL_RGBA4:
  344. case GL_RGB5_A1:
  345. case GL_RGB565:
  346. case GL_RGB8_OES:
  347. case GL_RGBA8_OES:
  348. case GL_DEPTH_COMPONENT16:
  349. return false;
  350. default:
  351. UNIMPLEMENTED();
  352. }
  353. return false;
  354. }
  355. }
  356. namespace es2dx
  357. {
  358. D3DCMPFUNC ConvertComparison(GLenum comparison)
  359. {
  360. D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
  361. switch (comparison)
  362. {
  363. case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
  364. case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
  365. case GL_LESS: d3dComp = D3DCMP_LESS; break;
  366. case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
  367. case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
  368. case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
  369. case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
  370. case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
  371. default: UNREACHABLE();
  372. }
  373. return d3dComp;
  374. }
  375. D3DCOLOR ConvertColor(gl::Color color)
  376. {
  377. return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
  378. gl::unorm<8>(color.green),
  379. gl::unorm<8>(color.blue),
  380. gl::unorm<8>(color.alpha));
  381. }
  382. D3DBLEND ConvertBlendFunc(GLenum blend)
  383. {
  384. D3DBLEND d3dBlend = D3DBLEND_ZERO;
  385. switch (blend)
  386. {
  387. case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
  388. case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
  389. case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
  390. case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
  391. case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
  392. case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
  393. case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
  394. case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
  395. case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
  396. case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
  397. case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
  398. case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
  399. case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
  400. case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
  401. case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
  402. default: UNREACHABLE();
  403. }
  404. return d3dBlend;
  405. }
  406. D3DBLENDOP ConvertBlendOp(GLenum blendOp)
  407. {
  408. D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
  409. switch (blendOp)
  410. {
  411. case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
  412. case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
  413. case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
  414. default: UNREACHABLE();
  415. }
  416. return d3dBlendOp;
  417. }
  418. D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
  419. {
  420. D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
  421. switch (stencilOp)
  422. {
  423. case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
  424. case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
  425. case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
  426. case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
  427. case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
  428. case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
  429. case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
  430. case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
  431. default: UNREACHABLE();
  432. }
  433. return d3dStencilOp;
  434. }
  435. D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
  436. {
  437. D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
  438. switch (wrap)
  439. {
  440. case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
  441. case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
  442. case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
  443. default: UNREACHABLE();
  444. }
  445. return d3dWrap;
  446. }
  447. D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
  448. {
  449. D3DCULL cull = D3DCULL_CCW;
  450. switch (cullFace)
  451. {
  452. case GL_FRONT:
  453. cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
  454. break;
  455. case GL_BACK:
  456. cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
  457. break;
  458. case GL_FRONT_AND_BACK:
  459. cull = D3DCULL_NONE; // culling will be handled during draw
  460. break;
  461. default: UNREACHABLE();
  462. }
  463. return cull;
  464. }
  465. DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
  466. {
  467. return (red ? D3DCOLORWRITEENABLE_RED : 0) |
  468. (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
  469. (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
  470. (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
  471. }
  472. D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter)
  473. {
  474. D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
  475. switch (magFilter)
  476. {
  477. case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
  478. case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
  479. default: UNREACHABLE();
  480. }
  481. return d3dMagFilter;
  482. }
  483. void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter)
  484. {
  485. switch (minFilter)
  486. {
  487. case GL_NEAREST:
  488. *d3dMinFilter = D3DTEXF_POINT;
  489. *d3dMipFilter = D3DTEXF_NONE;
  490. break;
  491. case GL_LINEAR:
  492. *d3dMinFilter = D3DTEXF_LINEAR;
  493. *d3dMipFilter = D3DTEXF_NONE;
  494. break;
  495. case GL_NEAREST_MIPMAP_NEAREST:
  496. *d3dMinFilter = D3DTEXF_POINT;
  497. *d3dMipFilter = D3DTEXF_POINT;
  498. break;
  499. case GL_LINEAR_MIPMAP_NEAREST:
  500. *d3dMinFilter = D3DTEXF_LINEAR;
  501. *d3dMipFilter = D3DTEXF_POINT;
  502. break;
  503. case GL_NEAREST_MIPMAP_LINEAR:
  504. *d3dMinFilter = D3DTEXF_POINT;
  505. *d3dMipFilter = D3DTEXF_LINEAR;
  506. break;
  507. case GL_LINEAR_MIPMAP_LINEAR:
  508. *d3dMinFilter = D3DTEXF_LINEAR;
  509. *d3dMipFilter = D3DTEXF_LINEAR;
  510. break;
  511. default:
  512. *d3dMinFilter = D3DTEXF_POINT;
  513. *d3dMipFilter = D3DTEXF_NONE;
  514. UNREACHABLE();
  515. }
  516. }
  517. unsigned int GetStencilSize(D3DFORMAT stencilFormat)
  518. {
  519. switch(stencilFormat)
  520. {
  521. case D3DFMT_D24FS8:
  522. case D3DFMT_D24S8:
  523. return 8;
  524. case D3DFMT_D24X4S4:
  525. return 4;
  526. case D3DFMT_D15S1:
  527. return 1;
  528. case D3DFMT_D16_LOCKABLE:
  529. case D3DFMT_D32:
  530. case D3DFMT_D24X8:
  531. case D3DFMT_D32F_LOCKABLE:
  532. case D3DFMT_D16:
  533. return 0;
  534. // case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
  535. // case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
  536. default: UNREACHABLE();
  537. }
  538. return 0;
  539. }
  540. unsigned int GetAlphaSize(D3DFORMAT colorFormat)
  541. {
  542. switch (colorFormat)
  543. {
  544. case D3DFMT_A16B16G16R16F:
  545. return 16;
  546. case D3DFMT_A32B32G32R32F:
  547. return 32;
  548. case D3DFMT_A2R10G10B10:
  549. return 2;
  550. case D3DFMT_A8R8G8B8:
  551. return 8;
  552. case D3DFMT_A1R5G5B5:
  553. return 1;
  554. case D3DFMT_X8R8G8B8:
  555. case D3DFMT_R5G6B5:
  556. return 0;
  557. default: UNREACHABLE();
  558. }
  559. return 0;
  560. }
  561. unsigned int GetRedSize(D3DFORMAT colorFormat)
  562. {
  563. switch (colorFormat)
  564. {
  565. case D3DFMT_A16B16G16R16F:
  566. return 16;
  567. case D3DFMT_A32B32G32R32F:
  568. return 32;
  569. case D3DFMT_A2R10G10B10:
  570. return 10;
  571. case D3DFMT_A8R8G8B8:
  572. case D3DFMT_X8R8G8B8:
  573. return 8;
  574. case D3DFMT_A1R5G5B5:
  575. case D3DFMT_R5G6B5:
  576. return 5;
  577. default: UNREACHABLE();
  578. }
  579. return 0;
  580. }
  581. unsigned int GetGreenSize(D3DFORMAT colorFormat)
  582. {
  583. switch (colorFormat)
  584. {
  585. case D3DFMT_A16B16G16R16F:
  586. return 16;
  587. case D3DFMT_A32B32G32R32F:
  588. return 32;
  589. case D3DFMT_A2R10G10B10:
  590. return 10;
  591. case D3DFMT_A8R8G8B8:
  592. case D3DFMT_X8R8G8B8:
  593. return 8;
  594. case D3DFMT_A1R5G5B5:
  595. return 5;
  596. case D3DFMT_R5G6B5:
  597. return 6;
  598. default: UNREACHABLE();
  599. }
  600. return 0;
  601. }
  602. unsigned int GetBlueSize(D3DFORMAT colorFormat)
  603. {
  604. switch (colorFormat)
  605. {
  606. case D3DFMT_A16B16G16R16F:
  607. return 16;
  608. case D3DFMT_A32B32G32R32F:
  609. return 32;
  610. case D3DFMT_A2R10G10B10:
  611. return 10;
  612. case D3DFMT_A8R8G8B8:
  613. case D3DFMT_X8R8G8B8:
  614. return 8;
  615. case D3DFMT_A1R5G5B5:
  616. case D3DFMT_R5G6B5:
  617. return 5;
  618. default: UNREACHABLE();
  619. }
  620. return 0;
  621. }
  622. unsigned int GetDepthSize(D3DFORMAT depthFormat)
  623. {
  624. switch (depthFormat)
  625. {
  626. case D3DFMT_D16_LOCKABLE: return 16;
  627. case D3DFMT_D32: return 32;
  628. case D3DFMT_D15S1: return 15;
  629. case D3DFMT_D24S8: return 24;
  630. case D3DFMT_D24X8: return 24;
  631. case D3DFMT_D24X4S4: return 24;
  632. case D3DFMT_D16: return 16;
  633. case D3DFMT_D32F_LOCKABLE: return 32;
  634. case D3DFMT_D24FS8: return 24;
  635. //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
  636. //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
  637. default:
  638. UNREACHABLE();
  639. }
  640. return 0;
  641. }
  642. bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
  643. D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
  644. {
  645. switch (primitiveType)
  646. {
  647. case GL_POINTS:
  648. *d3dPrimitiveType = D3DPT_POINTLIST;
  649. *d3dPrimitiveCount = elementCount;
  650. break;
  651. case GL_LINES:
  652. *d3dPrimitiveType = D3DPT_LINELIST;
  653. *d3dPrimitiveCount = elementCount / 2;
  654. break;
  655. case GL_LINE_LOOP:
  656. *d3dPrimitiveType = D3DPT_LINESTRIP;
  657. *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
  658. break;
  659. case GL_LINE_STRIP:
  660. *d3dPrimitiveType = D3DPT_LINESTRIP;
  661. *d3dPrimitiveCount = elementCount - 1;
  662. break;
  663. case GL_TRIANGLES:
  664. *d3dPrimitiveType = D3DPT_TRIANGLELIST;
  665. *d3dPrimitiveCount = elementCount / 3;
  666. break;
  667. case GL_TRIANGLE_STRIP:
  668. *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
  669. *d3dPrimitiveCount = elementCount - 2;
  670. break;
  671. case GL_TRIANGLE_FAN:
  672. *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
  673. *d3dPrimitiveCount = elementCount - 2;
  674. break;
  675. default:
  676. return false;
  677. }
  678. return true;
  679. }
  680. D3DFORMAT ConvertRenderbufferFormat(GLenum format)
  681. {
  682. switch (format)
  683. {
  684. case GL_RGBA4:
  685. case GL_RGB5_A1:
  686. case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
  687. case GL_RGB565: return D3DFMT_R5G6B5;
  688. case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
  689. case GL_DEPTH_COMPONENT16:
  690. case GL_STENCIL_INDEX8:
  691. case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
  692. default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
  693. }
  694. }
  695. GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
  696. {
  697. if (type == D3DMULTISAMPLE_NONMASKABLE)
  698. return 0;
  699. else
  700. return type;
  701. }
  702. D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
  703. {
  704. if (samples <= 1)
  705. return D3DMULTISAMPLE_NONE;
  706. else
  707. return (D3DMULTISAMPLE_TYPE)samples;
  708. }
  709. }
  710. namespace dx2es
  711. {
  712. GLenum ConvertBackBufferFormat(D3DFORMAT format)
  713. {
  714. switch (format)
  715. {
  716. case D3DFMT_A4R4G4B4: return GL_RGBA4;
  717. case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
  718. case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
  719. case D3DFMT_R5G6B5: return GL_RGB565;
  720. case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
  721. default:
  722. UNREACHABLE();
  723. }
  724. return GL_RGBA4;
  725. }
  726. GLenum ConvertDepthStencilFormat(D3DFORMAT format)
  727. {
  728. switch (format)
  729. {
  730. case D3DFMT_D16:
  731. case D3DFMT_D24X8:
  732. return GL_DEPTH_COMPONENT16;
  733. case D3DFMT_D24S8:
  734. return GL_DEPTH24_STENCIL8_OES;
  735. default:
  736. UNREACHABLE();
  737. }
  738. return GL_DEPTH24_STENCIL8_OES;
  739. }
  740. }