diff options
author | Andrew Knight <andrew.knight@digia.com> | 2014-08-05 12:59:44 +0300 |
---|---|---|
committer | Andrew Knight <andrew.knight@digia.com> | 2014-08-05 16:43:22 +0200 |
commit | a6a12d8c0fc918972c15268f749ecc7c90b95d6c (patch) | |
tree | cb6d986d30ef97e932ab51768854d5d9b46729d3 /src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp | |
parent | 14f9c09542bd6cc19430473da9ce4c68f239ec7d (diff) |
ANGLE: upgrade to 2.1~07d49ef5350a
This version of ANGLE provides partial ES3 support, numerous
bug fixes, and several potentially useful vendor extensions.
All patches have been rebased. The following changes are noted:
0000-General-fixes-for-ANGLE-2.1.patch
contains compile fixes for the new ANGLE
0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch
has incorporated patch 0015.
0007-Make-DX9-DX11-mutually-exclusive.patch
has been removed as it was fixed upstream.
0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch
has been moved up to fill the patch number gap.
0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
now contains patch 0014 and 0017.
0013-ANGLE-Allow-for-universal-program-binaries.patch
has been removed as it is no longer relevant.
0014-ANGLE-D3D11-Fix-internal-index-buffer-for-level-9-ha.patch
has been merged with patch 0010.
0015-ANGLE-Don-t-export-DLLMain-functions-for-static-buil.patch
has been merged with patch 0004.
0016-ANGLE-WinRT-Call-Trim-when-application-suspends.patch
has been removed and will be replaced by a follow-up patch using a
different technique.
0017-ANGLE-D3D11-Don-t-use-mipmaps-in-level-9-textures.patch
has been merged with patch 0010.
0018-ANGLE-WinRT-Create-swap-chain-using-physical-resolut.patch
has been removed and will be replaced by a follow-up patch extending
the EGL_ANGLE_window_fixed_size extension.
0019-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch
is now patch 0007.
[ChangeLog][Third-party libraries] ANGLE has been upgraded to
version 2.1, bringing partial support for OpenGL ES3 over
Direct3D 11, numerous bug fixes, and several new vendor extensions.
Change-Id: I6d95ce1480462d67228d83c1e5c74a1706b5b21c
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp new file mode 100644 index 0000000000..68e5378fbb --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp @@ -0,0 +1,409 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// renderer9_utils.cpp: Conversion functions and other utility routines +// specific to the D3D9 renderer. + +#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h" +#include "libGLESv2/formatutils.h" +#include "common/mathutil.h" +#include "libGLESv2/Context.h" + +#include "common/debug.h" + +#include "third_party/systeminfo/SystemInfo.h" + +namespace rx +{ + +namespace gl_d3d9 +{ + +D3DCMPFUNC ConvertComparison(GLenum comparison) +{ + D3DCMPFUNC d3dComp = D3DCMP_ALWAYS; + switch (comparison) + { + case GL_NEVER: d3dComp = D3DCMP_NEVER; break; + case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break; + case GL_LESS: d3dComp = D3DCMP_LESS; break; + case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break; + case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break; + case GL_GREATER: d3dComp = D3DCMP_GREATER; break; + case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break; + case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break; + default: UNREACHABLE(); + } + + return d3dComp; +} + +D3DCOLOR ConvertColor(gl::ColorF color) +{ + return D3DCOLOR_RGBA(gl::unorm<8>(color.red), + gl::unorm<8>(color.green), + gl::unorm<8>(color.blue), + gl::unorm<8>(color.alpha)); +} + +D3DBLEND ConvertBlendFunc(GLenum blend) +{ + D3DBLEND d3dBlend = D3DBLEND_ZERO; + + switch (blend) + { + case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break; + case GL_ONE: d3dBlend = D3DBLEND_ONE; break; + case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break; + case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break; + case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break; + case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break; + case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break; + case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break; + case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break; + case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break; + case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; + case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break; + case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; + case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break; + default: UNREACHABLE(); + } + + return d3dBlend; +} + +D3DBLENDOP ConvertBlendOp(GLenum blendOp) +{ + D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD; + + switch (blendOp) + { + case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break; + case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break; + case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break; + case GL_MIN_EXT: d3dBlendOp = D3DBLENDOP_MIN; break; + case GL_MAX_EXT: d3dBlendOp = D3DBLENDOP_MAX; break; + default: UNREACHABLE(); + } + + return d3dBlendOp; +} + +D3DSTENCILOP ConvertStencilOp(GLenum stencilOp) +{ + D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP; + + switch (stencilOp) + { + case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break; + case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break; + case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break; + case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break; + case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break; + case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break; + case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break; + case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break; + default: UNREACHABLE(); + } + + return d3dStencilOp; +} + +D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap) +{ + D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP; + + switch (wrap) + { + case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break; + case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break; + case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break; + default: UNREACHABLE(); + } + + return d3dWrap; +} + +D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace) +{ + D3DCULL cull = D3DCULL_CCW; + switch (cullFace) + { + case GL_FRONT: + cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW); + break; + case GL_BACK: + cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW); + break; + case GL_FRONT_AND_BACK: + cull = D3DCULL_NONE; // culling will be handled during draw + break; + default: UNREACHABLE(); + } + + return cull; +} + +D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) +{ + D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; + + switch (cubeFace) + { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + face = D3DCUBEMAP_FACE_POSITIVE_X; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + face = D3DCUBEMAP_FACE_NEGATIVE_X; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + face = D3DCUBEMAP_FACE_POSITIVE_Y; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + face = D3DCUBEMAP_FACE_NEGATIVE_Y; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + face = D3DCUBEMAP_FACE_POSITIVE_Z; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = D3DCUBEMAP_FACE_NEGATIVE_Z; + break; + default: UNREACHABLE(); + } + + return face; +} + +DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha) +{ + return (red ? D3DCOLORWRITEENABLE_RED : 0) | + (green ? D3DCOLORWRITEENABLE_GREEN : 0) | + (blue ? D3DCOLORWRITEENABLE_BLUE : 0) | + (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0); +} + +D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) +{ + if (maxAnisotropy > 1.0f) + { + return D3DTEXF_ANISOTROPIC; + } + + D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT; + switch (magFilter) + { + case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break; + case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break; + default: UNREACHABLE(); + } + + return d3dMagFilter; +} + +void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy) +{ + switch (minFilter) + { + case GL_NEAREST: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_NONE; + break; + case GL_LINEAR: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_LINEAR; + break; + default: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_NONE; + UNREACHABLE(); + } + + if (maxAnisotropy > 1.0f) + { + *d3dMinFilter = D3DTEXF_ANISOTROPIC; + } +} + +} + +namespace d3d9_gl +{ + +static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3D9 *d3d9, D3DDEVTYPE deviceType, + UINT adapter, D3DFORMAT adapterFormat) +{ + gl::TextureCaps textureCaps; + + D3DFORMAT renderFormat = gl_d3d9::GetRenderFormat(internalFormat); + if (gl::GetDepthBits(internalFormat) > 0 || gl::GetStencilBits(internalFormat) > 0) + { + textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, renderFormat)); + textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, renderFormat)); + textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, renderFormat)) || + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, renderFormat)); + } + else + { + D3DFORMAT textureFormat = gl_d3d9::GetTextureFormat(internalFormat); + textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, textureFormat)) && + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_CUBETEXTURE, textureFormat)); + textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, textureFormat)); + textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, textureFormat)) || + SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, textureFormat)); + } + + textureCaps.sampleCounts.insert(1); + for (size_t i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) + { + D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); + + HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, renderFormat, TRUE, multisampleType, NULL); + if (SUCCEEDED(result)) + { + textureCaps.sampleCounts.insert(i); + } + } + + return textureCaps; +} + +void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions) +{ + D3DCAPS9 deviceCaps; + if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps))) + { + // Can't continue with out device caps + return; + } + + D3DDISPLAYMODE currentDisplayMode; + d3d9->GetAdapterDisplayMode(adapter, ¤tDisplayMode); + + const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); + for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) + { + gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter, + currentDisplayMode.Format); + textureCapsMap->insert(*internalFormat, textureCaps); + } + + // GL core feature limits + caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max()); + + // 3D textures are unimplemented in D3D9 + caps->max3DTextureSize = 1; + + // Only one limit in GL, use the minimum dimension + caps->max2DTextureSize = std::min(deviceCaps.MaxTextureWidth, deviceCaps.MaxTextureHeight); + + // D3D treats cube maps as a special case of 2D textures + caps->maxCubeMapTextureSize = caps->max2DTextureSize; + + // Array textures are not available in D3D9 + caps->maxArrayTextureLayers = 1; + + // ES3-only feature + caps->maxLODBias = 0.0f; + + // No specific limits on render target size, maximum 2D texture size is equivalent + caps->maxRenderbufferSize = caps->max2DTextureSize; + + // Draw buffers are not supported in D3D9 + caps->maxDrawBuffers = 1; + caps->maxColorAttachments = 1; + + // No specific limits on viewport size, maximum 2D texture size is equivalent + caps->maxViewportWidth = caps->max2DTextureSize; + caps->maxViewportHeight = caps->maxViewportWidth; + + // Point size is clamped to 1.0f when the shader model is less than 3 + caps->minAliasedPointSize = 1.0f; + caps->maxAliasedPointSize = ((D3DSHADER_VERSION_MAJOR(deviceCaps.PixelShaderVersion) >= 3) ? deviceCaps.MaxPointSize : 1.0f); + + // Wide lines not supported + caps->minAliasedLineWidth = 1.0f; + caps->maxAliasedLineWidth = 1.0f; + + // GL extension support + extensions->setTextureExtensionSupport(*textureCapsMap); + extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16); + extensions->packedDepthStencil = true; + extensions->getProgramBinary = true; + extensions->rgb8rgba8 = true; + extensions->readFormatBGRA = true; + extensions->pixelBufferObject = false; + extensions->mapBuffer = false; + extensions->mapBufferRange = false; + + // ATI cards on XP have problems with non-power-of-two textures. + D3DADAPTER_IDENTIFIER9 adapterId = { 0 }; + if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId))) + { + extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && + !(isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD); + } + else + { + extensions->textureNPOT = false; + } + + extensions->drawBuffers = false; + extensions->textureStorage = true; + + // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec + extensions->textureFilterAnisotropic = (deviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && deviceCaps.MaxAnisotropy >= 2; + extensions->maxTextureAnisotropy = static_cast<GLfloat>(deviceCaps.MaxAnisotropy); + + // Check occlusion query support by trying to create one + IDirect3DQuery9 *occlusionQuery = NULL; + extensions->occlusionQueryBoolean = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery; + SafeRelease(occlusionQuery); + + // Check event query support by trying to create one + IDirect3DQuery9 *eventQuery = NULL; + extensions->fence = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery; + SafeRelease(eventQuery); + + extensions->timerQuery = false; // Unimplemented + extensions->robustness = true; + extensions->blendMinMax = true; + extensions->framebufferBlit = true; + extensions->framebufferMultisample = true; + extensions->instancedArrays = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); + extensions->packReverseRowOrder = true; + extensions->standardDerivatives = (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0; + extensions->shaderTextureLOD = true; + extensions->fragDepth = true; + extensions->textureUsage = true; + extensions->translatedShaderSource = true; + extensions->colorBufferFloat = false; +} + +} + +} |