1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/renderer/renderer9_utils.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,500 @@ 1.4 +#include "precompiled.h" 1.5 +// 1.6 +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 1.7 +// Use of this source code is governed by a BSD-style license that can be 1.8 +// found in the LICENSE file. 1.9 +// 1.10 + 1.11 +// renderer9_utils.cpp: Conversion functions and other utility routines 1.12 +// specific to the D3D9 renderer. 1.13 + 1.14 +#include "libGLESv2/renderer/renderer9_utils.h" 1.15 +#include "libGLESv2/mathutil.h" 1.16 +#include "libGLESv2/Context.h" 1.17 + 1.18 +#include "common/debug.h" 1.19 + 1.20 +namespace gl_d3d9 1.21 +{ 1.22 + 1.23 +D3DCMPFUNC ConvertComparison(GLenum comparison) 1.24 +{ 1.25 + D3DCMPFUNC d3dComp = D3DCMP_ALWAYS; 1.26 + switch (comparison) 1.27 + { 1.28 + case GL_NEVER: d3dComp = D3DCMP_NEVER; break; 1.29 + case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break; 1.30 + case GL_LESS: d3dComp = D3DCMP_LESS; break; 1.31 + case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break; 1.32 + case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break; 1.33 + case GL_GREATER: d3dComp = D3DCMP_GREATER; break; 1.34 + case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break; 1.35 + case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break; 1.36 + default: UNREACHABLE(); 1.37 + } 1.38 + 1.39 + return d3dComp; 1.40 +} 1.41 + 1.42 +D3DCOLOR ConvertColor(gl::Color color) 1.43 +{ 1.44 + return D3DCOLOR_RGBA(gl::unorm<8>(color.red), 1.45 + gl::unorm<8>(color.green), 1.46 + gl::unorm<8>(color.blue), 1.47 + gl::unorm<8>(color.alpha)); 1.48 +} 1.49 + 1.50 +D3DBLEND ConvertBlendFunc(GLenum blend) 1.51 +{ 1.52 + D3DBLEND d3dBlend = D3DBLEND_ZERO; 1.53 + 1.54 + switch (blend) 1.55 + { 1.56 + case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break; 1.57 + case GL_ONE: d3dBlend = D3DBLEND_ONE; break; 1.58 + case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break; 1.59 + case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break; 1.60 + case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break; 1.61 + case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break; 1.62 + case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break; 1.63 + case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break; 1.64 + case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break; 1.65 + case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break; 1.66 + case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break; 1.67 + case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; 1.68 + case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break; 1.69 + case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; 1.70 + case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break; 1.71 + default: UNREACHABLE(); 1.72 + } 1.73 + 1.74 + return d3dBlend; 1.75 +} 1.76 + 1.77 +D3DBLENDOP ConvertBlendOp(GLenum blendOp) 1.78 +{ 1.79 + D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD; 1.80 + 1.81 + switch (blendOp) 1.82 + { 1.83 + case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break; 1.84 + case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break; 1.85 + case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break; 1.86 + default: UNREACHABLE(); 1.87 + } 1.88 + 1.89 + return d3dBlendOp; 1.90 +} 1.91 + 1.92 +D3DSTENCILOP ConvertStencilOp(GLenum stencilOp) 1.93 +{ 1.94 + D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP; 1.95 + 1.96 + switch (stencilOp) 1.97 + { 1.98 + case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break; 1.99 + case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break; 1.100 + case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break; 1.101 + case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break; 1.102 + case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break; 1.103 + case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break; 1.104 + case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break; 1.105 + case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break; 1.106 + default: UNREACHABLE(); 1.107 + } 1.108 + 1.109 + return d3dStencilOp; 1.110 +} 1.111 + 1.112 +D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap) 1.113 +{ 1.114 + D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP; 1.115 + 1.116 + switch (wrap) 1.117 + { 1.118 + case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break; 1.119 + case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break; 1.120 + case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break; 1.121 + default: UNREACHABLE(); 1.122 + } 1.123 + 1.124 + return d3dWrap; 1.125 +} 1.126 + 1.127 +D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace) 1.128 +{ 1.129 + D3DCULL cull = D3DCULL_CCW; 1.130 + switch (cullFace) 1.131 + { 1.132 + case GL_FRONT: 1.133 + cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW); 1.134 + break; 1.135 + case GL_BACK: 1.136 + cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW); 1.137 + break; 1.138 + case GL_FRONT_AND_BACK: 1.139 + cull = D3DCULL_NONE; // culling will be handled during draw 1.140 + break; 1.141 + default: UNREACHABLE(); 1.142 + } 1.143 + 1.144 + return cull; 1.145 +} 1.146 + 1.147 +D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) 1.148 +{ 1.149 + D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; 1.150 + 1.151 + switch (cubeFace) 1.152 + { 1.153 + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1.154 + face = D3DCUBEMAP_FACE_POSITIVE_X; 1.155 + break; 1.156 + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1.157 + face = D3DCUBEMAP_FACE_NEGATIVE_X; 1.158 + break; 1.159 + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1.160 + face = D3DCUBEMAP_FACE_POSITIVE_Y; 1.161 + break; 1.162 + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1.163 + face = D3DCUBEMAP_FACE_NEGATIVE_Y; 1.164 + break; 1.165 + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1.166 + face = D3DCUBEMAP_FACE_POSITIVE_Z; 1.167 + break; 1.168 + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1.169 + face = D3DCUBEMAP_FACE_NEGATIVE_Z; 1.170 + break; 1.171 + default: UNREACHABLE(); 1.172 + } 1.173 + 1.174 + return face; 1.175 +} 1.176 + 1.177 +DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha) 1.178 +{ 1.179 + return (red ? D3DCOLORWRITEENABLE_RED : 0) | 1.180 + (green ? D3DCOLORWRITEENABLE_GREEN : 0) | 1.181 + (blue ? D3DCOLORWRITEENABLE_BLUE : 0) | 1.182 + (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0); 1.183 +} 1.184 + 1.185 +D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) 1.186 +{ 1.187 + if (maxAnisotropy > 1.0f) 1.188 + { 1.189 + return D3DTEXF_ANISOTROPIC; 1.190 + } 1.191 + 1.192 + D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT; 1.193 + switch (magFilter) 1.194 + { 1.195 + case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break; 1.196 + case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break; 1.197 + default: UNREACHABLE(); 1.198 + } 1.199 + 1.200 + return d3dMagFilter; 1.201 +} 1.202 + 1.203 +void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy) 1.204 +{ 1.205 + switch (minFilter) 1.206 + { 1.207 + case GL_NEAREST: 1.208 + *d3dMinFilter = D3DTEXF_POINT; 1.209 + *d3dMipFilter = D3DTEXF_NONE; 1.210 + break; 1.211 + case GL_LINEAR: 1.212 + *d3dMinFilter = D3DTEXF_LINEAR; 1.213 + *d3dMipFilter = D3DTEXF_NONE; 1.214 + break; 1.215 + case GL_NEAREST_MIPMAP_NEAREST: 1.216 + *d3dMinFilter = D3DTEXF_POINT; 1.217 + *d3dMipFilter = D3DTEXF_POINT; 1.218 + break; 1.219 + case GL_LINEAR_MIPMAP_NEAREST: 1.220 + *d3dMinFilter = D3DTEXF_LINEAR; 1.221 + *d3dMipFilter = D3DTEXF_POINT; 1.222 + break; 1.223 + case GL_NEAREST_MIPMAP_LINEAR: 1.224 + *d3dMinFilter = D3DTEXF_POINT; 1.225 + *d3dMipFilter = D3DTEXF_LINEAR; 1.226 + break; 1.227 + case GL_LINEAR_MIPMAP_LINEAR: 1.228 + *d3dMinFilter = D3DTEXF_LINEAR; 1.229 + *d3dMipFilter = D3DTEXF_LINEAR; 1.230 + break; 1.231 + default: 1.232 + *d3dMinFilter = D3DTEXF_POINT; 1.233 + *d3dMipFilter = D3DTEXF_NONE; 1.234 + UNREACHABLE(); 1.235 + } 1.236 + 1.237 + if (maxAnisotropy > 1.0f) 1.238 + { 1.239 + *d3dMinFilter = D3DTEXF_ANISOTROPIC; 1.240 + } 1.241 +} 1.242 + 1.243 +D3DFORMAT ConvertRenderbufferFormat(GLenum format) 1.244 +{ 1.245 + switch (format) 1.246 + { 1.247 + case GL_NONE: return D3DFMT_NULL; 1.248 + case GL_RGBA4: 1.249 + case GL_RGB5_A1: 1.250 + case GL_RGBA8_OES: return D3DFMT_A8R8G8B8; 1.251 + case GL_RGB565: return D3DFMT_R5G6B5; 1.252 + case GL_RGB8_OES: return D3DFMT_X8R8G8B8; 1.253 + case GL_DEPTH_COMPONENT16: 1.254 + case GL_STENCIL_INDEX8: 1.255 + case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8; 1.256 + default: UNREACHABLE(); return D3DFMT_A8R8G8B8; 1.257 + } 1.258 +} 1.259 + 1.260 +D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples) 1.261 +{ 1.262 + if (samples <= 1) 1.263 + return D3DMULTISAMPLE_NONE; 1.264 + else 1.265 + return (D3DMULTISAMPLE_TYPE)samples; 1.266 +} 1.267 + 1.268 +} 1.269 + 1.270 +namespace d3d9_gl 1.271 +{ 1.272 + 1.273 +unsigned int GetStencilSize(D3DFORMAT stencilFormat) 1.274 +{ 1.275 + if (stencilFormat == D3DFMT_INTZ) 1.276 + { 1.277 + return 8; 1.278 + } 1.279 + switch(stencilFormat) 1.280 + { 1.281 + case D3DFMT_D24FS8: 1.282 + case D3DFMT_D24S8: 1.283 + return 8; 1.284 + case D3DFMT_D24X4S4: 1.285 + return 4; 1.286 + case D3DFMT_D15S1: 1.287 + return 1; 1.288 + case D3DFMT_D16_LOCKABLE: 1.289 + case D3DFMT_D32: 1.290 + case D3DFMT_D24X8: 1.291 + case D3DFMT_D32F_LOCKABLE: 1.292 + case D3DFMT_D16: 1.293 + return 0; 1.294 + //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only 1.295 + //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only 1.296 + default: 1.297 + return 0; 1.298 + } 1.299 +} 1.300 + 1.301 +unsigned int GetAlphaSize(D3DFORMAT colorFormat) 1.302 +{ 1.303 + switch (colorFormat) 1.304 + { 1.305 + case D3DFMT_A16B16G16R16F: 1.306 + return 16; 1.307 + case D3DFMT_A32B32G32R32F: 1.308 + return 32; 1.309 + case D3DFMT_A2R10G10B10: 1.310 + return 2; 1.311 + case D3DFMT_A8R8G8B8: 1.312 + return 8; 1.313 + case D3DFMT_A1R5G5B5: 1.314 + return 1; 1.315 + case D3DFMT_X8R8G8B8: 1.316 + case D3DFMT_R5G6B5: 1.317 + return 0; 1.318 + default: 1.319 + return 0; 1.320 + } 1.321 +} 1.322 + 1.323 +GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type) 1.324 +{ 1.325 + if (type == D3DMULTISAMPLE_NONMASKABLE) 1.326 + return 0; 1.327 + else 1.328 + return type; 1.329 +} 1.330 + 1.331 +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) 1.332 +{ 1.333 + switch (d3dformat) 1.334 + { 1.335 + case D3DFMT_L8: 1.336 + return (format == GL_LUMINANCE); 1.337 + case D3DFMT_A8L8: 1.338 + return (format == GL_LUMINANCE_ALPHA); 1.339 + case D3DFMT_DXT1: 1.340 + return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT); 1.341 + case D3DFMT_DXT3: 1.342 + return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); 1.343 + case D3DFMT_DXT5: 1.344 + return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); 1.345 + case D3DFMT_A8R8G8B8: 1.346 + case D3DFMT_A16B16G16R16F: 1.347 + case D3DFMT_A32B32G32R32F: 1.348 + return (format == GL_RGBA || format == GL_BGRA_EXT); 1.349 + case D3DFMT_X8R8G8B8: 1.350 + return (format == GL_RGB); 1.351 + default: 1.352 + if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format)) 1.353 + return true; 1.354 + return false; 1.355 + } 1.356 +} 1.357 + 1.358 +GLenum ConvertBackBufferFormat(D3DFORMAT format) 1.359 +{ 1.360 + switch (format) 1.361 + { 1.362 + case D3DFMT_A4R4G4B4: return GL_RGBA4; 1.363 + case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; 1.364 + case D3DFMT_A1R5G5B5: return GL_RGB5_A1; 1.365 + case D3DFMT_R5G6B5: return GL_RGB565; 1.366 + case D3DFMT_X8R8G8B8: return GL_RGB8_OES; 1.367 + default: 1.368 + UNREACHABLE(); 1.369 + } 1.370 + 1.371 + return GL_RGBA4; 1.372 +} 1.373 + 1.374 +GLenum ConvertDepthStencilFormat(D3DFORMAT format) 1.375 +{ 1.376 + if (format == D3DFMT_INTZ) 1.377 + { 1.378 + return GL_DEPTH24_STENCIL8_OES; 1.379 + } 1.380 + switch (format) 1.381 + { 1.382 + case D3DFMT_D16: 1.383 + case D3DFMT_D24X8: 1.384 + return GL_DEPTH_COMPONENT16; 1.385 + case D3DFMT_D24S8: 1.386 + return GL_DEPTH24_STENCIL8_OES; 1.387 + case D3DFMT_UNKNOWN: 1.388 + return GL_NONE; 1.389 + default: 1.390 + UNREACHABLE(); 1.391 + } 1.392 + 1.393 + return GL_DEPTH24_STENCIL8_OES; 1.394 +} 1.395 + 1.396 +GLenum ConvertRenderTargetFormat(D3DFORMAT format) 1.397 +{ 1.398 + if (format == D3DFMT_INTZ) 1.399 + { 1.400 + return GL_DEPTH24_STENCIL8_OES; 1.401 + } 1.402 + 1.403 + switch (format) 1.404 + { 1.405 + case D3DFMT_A4R4G4B4: return GL_RGBA4; 1.406 + case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; 1.407 + case D3DFMT_A1R5G5B5: return GL_RGB5_A1; 1.408 + case D3DFMT_R5G6B5: return GL_RGB565; 1.409 + case D3DFMT_X8R8G8B8: return GL_RGB8_OES; 1.410 + case D3DFMT_D16: 1.411 + case D3DFMT_D24X8: 1.412 + return GL_DEPTH_COMPONENT16; 1.413 + case D3DFMT_D24S8: 1.414 + return GL_DEPTH24_STENCIL8_OES; 1.415 + case D3DFMT_UNKNOWN: 1.416 + return GL_NONE; 1.417 + default: 1.418 + UNREACHABLE(); 1.419 + } 1.420 + 1.421 + return GL_RGBA4; 1.422 +} 1.423 + 1.424 +GLenum GetEquivalentFormat(D3DFORMAT format) 1.425 +{ 1.426 + if (format == D3DFMT_INTZ) 1.427 + return GL_DEPTH24_STENCIL8_OES; 1.428 + if (format == D3DFMT_NULL) 1.429 + return GL_NONE; 1.430 + 1.431 + switch (format) 1.432 + { 1.433 + case D3DFMT_A4R4G4B4: return GL_RGBA4; 1.434 + case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; 1.435 + case D3DFMT_A1R5G5B5: return GL_RGB5_A1; 1.436 + case D3DFMT_R5G6B5: return GL_RGB565; 1.437 + case D3DFMT_X8R8G8B8: return GL_RGB8_OES; 1.438 + case D3DFMT_D16: return GL_DEPTH_COMPONENT16; 1.439 + case D3DFMT_D24S8: return GL_DEPTH24_STENCIL8_OES; 1.440 + case D3DFMT_UNKNOWN: return GL_NONE; 1.441 + case D3DFMT_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; 1.442 + case D3DFMT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; 1.443 + case D3DFMT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; 1.444 + case D3DFMT_A32B32G32R32F: return GL_RGBA32F_EXT; 1.445 + case D3DFMT_A16B16G16R16F: return GL_RGBA16F_EXT; 1.446 + case D3DFMT_L8: return GL_LUMINANCE8_EXT; 1.447 + case D3DFMT_A8L8: return GL_LUMINANCE8_ALPHA8_EXT; 1.448 + default: UNREACHABLE(); 1.449 + return GL_NONE; 1.450 + } 1.451 +} 1.452 + 1.453 +} 1.454 + 1.455 +namespace d3d9 1.456 +{ 1.457 + 1.458 +bool IsCompressedFormat(D3DFORMAT surfaceFormat) 1.459 +{ 1.460 + switch(surfaceFormat) 1.461 + { 1.462 + case D3DFMT_DXT1: 1.463 + case D3DFMT_DXT2: 1.464 + case D3DFMT_DXT3: 1.465 + case D3DFMT_DXT4: 1.466 + case D3DFMT_DXT5: 1.467 + return true; 1.468 + default: 1.469 + return false; 1.470 + } 1.471 +} 1.472 + 1.473 +size_t ComputeRowSize(D3DFORMAT format, unsigned int width) 1.474 +{ 1.475 + if (format == D3DFMT_INTZ) 1.476 + { 1.477 + return 4 * width; 1.478 + } 1.479 + switch (format) 1.480 + { 1.481 + case D3DFMT_L8: 1.482 + return 1 * width; 1.483 + case D3DFMT_A8L8: 1.484 + return 2 * width; 1.485 + case D3DFMT_X8R8G8B8: 1.486 + case D3DFMT_A8R8G8B8: 1.487 + return 4 * width; 1.488 + case D3DFMT_A16B16G16R16F: 1.489 + return 8 * width; 1.490 + case D3DFMT_A32B32G32R32F: 1.491 + return 16 * width; 1.492 + case D3DFMT_DXT1: 1.493 + return 8 * ((width + 3) / 4); 1.494 + case D3DFMT_DXT3: 1.495 + case D3DFMT_DXT5: 1.496 + return 16 * ((width + 3) / 4); 1.497 + default: 1.498 + UNREACHABLE(); 1.499 + return 0; 1.500 + } 1.501 +} 1.502 + 1.503 +}