1 #include "precompiled.h" 2 // 3 // Copyright (c) 2013 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 // formatutils9.cpp: Queries for GL image formats and their translations to D3D9 9 // formats. 10 11 #include "libGLESv2/renderer/d3d9/formatutils9.h" 12 #include "libGLESv2/renderer/d3d9/Renderer9.h" 13 #include "libGLESv2/renderer/generatemip.h" 14 #include "libGLESv2/renderer/loadimage.h" 15 #include "libGLESv2/renderer/copyimage.h" 16 #include "libGLESv2/renderer/vertexconversion.h" 17 18 namespace rx 19 { 20 21 // Each GL internal format corresponds to one D3D format and data loading function. 22 // Due to not all formats being available all the time, some of the function/format types are wrapped 23 // in templates that perform format support queries on a Renderer9 object which is supplied 24 // when requesting the function or format. 25 26 typedef bool ((Renderer9::*Renderer9FormatCheckFunction)(void) const); 27 typedef LoadImageFunction (*RendererCheckLoadFunction)(const Renderer9 *renderer); 28 29 template <Renderer9FormatCheckFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> 30 LoadImageFunction RendererCheckLoad(const Renderer9 *renderer) 31 { 32 return ((renderer->*pred)()) ? prefered : fallback; 33 } 34 35 template <LoadImageFunction loadFunc> 36 LoadImageFunction SimpleLoad(const Renderer9 *renderer) 37 { 38 return loadFunc; 39 } 40 41 LoadImageFunction UnreachableLoad(const Renderer9 *renderer) 42 { 43 UNREACHABLE(); 44 return NULL; 45 } 46 47 typedef bool (*FallbackPredicateFunction)(void); 48 49 template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> 50 LoadImageFunction FallbackLoadFunction(const Renderer9 *renderer) 51 { 52 return pred() ? prefered : fallback; 53 } 54 55 typedef D3DFORMAT (*FormatQueryFunction)(const rx::Renderer9 *renderer); 56 57 template <Renderer9FormatCheckFunction pred, D3DFORMAT prefered, D3DFORMAT fallback> 58 D3DFORMAT CheckFormatSupport(const rx::Renderer9 *renderer) 59 { 60 return (renderer->*pred)() ? prefered : fallback; 61 } 62 63 template <D3DFORMAT format> 64 D3DFORMAT D3D9Format(const rx::Renderer9 *renderer) 65 { 66 return format; 67 } 68 69 struct D3D9FormatInfo 70 { 71 FormatQueryFunction mTexFormat; 72 FormatQueryFunction mRenderFormat; 73 RendererCheckLoadFunction mLoadFunction; 74 75 D3D9FormatInfo() 76 : mTexFormat(NULL), mRenderFormat(NULL), mLoadFunction(NULL) 77 { } 78 79 D3D9FormatInfo(FormatQueryFunction textureFormat, FormatQueryFunction renderFormat, RendererCheckLoadFunction loadFunc) 80 : mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc) 81 { } 82 }; 83 84 const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))); 85 const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))); 86 87 typedef std::pair<GLenum, D3D9FormatInfo> D3D9FormatPair; 88 typedef std::map<GLenum, D3D9FormatInfo> D3D9FormatMap; 89 90 static D3D9FormatMap BuildD3D9FormatMap() 91 { 92 D3D9FormatMap map; 93 94 // | Internal format | Texture format | Render format | Load function | 95 map.insert(D3D9FormatPair(GL_NONE, D3D9FormatInfo(D3D9Format<D3DFMT_NULL>, D3D9Format<D3DFMT_NULL>, UnreachableLoad ))); 96 97 map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); 98 map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D32>, UnreachableLoad ))); 99 map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); 100 map.insert(D3D9FormatPair(GL_STENCIL_INDEX8, D3D9FormatInfo(D3D9Format<D3DFMT_UNKNOWN>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); // TODO: What's the texture format? 101 102 map.insert(D3D9FormatPair(GL_RGBA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadToNative<GLfloat, 4> > ))); 103 map.insert(D3D9FormatPair(GL_RGB32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadToNative3To4<GLfloat, gl::Float32One> >))); 104 map.insert(D3D9FormatPair(GL_RG32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_G32R32F>, D3D9Format<D3DFMT_G32R32F>, SimpleLoad<loadToNative<GLfloat, 2> > ))); 105 map.insert(D3D9FormatPair(GL_R32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_R32F>, D3D9Format<D3DFMT_R32F>, SimpleLoad<loadToNative<GLfloat, 1> > ))); 106 map.insert(D3D9FormatPair(GL_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaFloatDataToRGBA> ))); 107 map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceFloatDataToRGBA> ))); 108 map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaFloatDataToRGBA> ))); 109 110 map.insert(D3D9FormatPair(GL_RGBA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadToNative<GLhalf, 4> > ))); 111 map.insert(D3D9FormatPair(GL_RGB16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadToNative3To4<GLhalf, gl::Float16One> >))); 112 map.insert(D3D9FormatPair(GL_RG16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_G16R16F>, D3D9Format<D3DFMT_G16R16F>, SimpleLoad<loadToNative<GLhalf, 2> > ))); 113 map.insert(D3D9FormatPair(GL_R16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_R16F>, D3D9Format<D3DFMT_R16F>, SimpleLoad<loadToNative<GLhalf, 1> > ))); 114 map.insert(D3D9FormatPair(GL_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaHalfFloatDataToRGBA> ))); 115 map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceHalfFloatDataToRGBA> ))); 116 map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaHalfFloatDataToRGBA>))); 117 118 map.insert(D3D9FormatPair(GL_ALPHA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadAlphaDataToBGRASSE2, loadAlphaDataToBGRA>))); 119 120 map.insert(D3D9FormatPair(GL_RGB8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRGBUByteDataToBGRX> ))); 121 map.insert(D3D9FormatPair(GL_RGB565, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getRGB565TextureSupport, D3DFMT_R5G6B5, D3DFMT_X8R8G8B8>, CheckFormatSupport<&Renderer9::getRGB565TextureSupport, D3DFMT_R5G6B5, D3DFMT_X8R8G8B8>, RendererCheckLoad<&Renderer9::getRGB565TextureSupport, loadToNative<GLushort, 1>, loadRGB565DataToBGRA>))); 122 map.insert(D3D9FormatPair(GL_RGBA8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadRGBAUByteDataToBGRASSE2, loadRGBAUByteDataToBGRA>))); 123 map.insert(D3D9FormatPair(GL_RGBA4, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToBGRA> ))); 124 map.insert(D3D9FormatPair(GL_RGB5_A1, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToBGRA> ))); 125 map.insert(D3D9FormatPair(GL_R8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRUByteDataToBGRX> ))); 126 map.insert(D3D9FormatPair(GL_RG8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRGUByteDataToBGRX> ))); 127 128 map.insert(D3D9FormatPair(GL_BGRA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadToNative<GLubyte, 4> > ))); 129 map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToRGBA> ))); 130 map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToRGBA> ))); 131 132 map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >))); 133 map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >))); 134 map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT3>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >))); 135 map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT5>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >))); 136 137 // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and 138 // then changing the format and loading function appropriately. 139 map.insert(D3D9FormatPair(GL_LUMINANCE8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceTextureSupport, D3DFMT_L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 1>, loadLuminanceDataToBGRA>))); 140 map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceAlphaTextureSupport, D3DFMT_A8L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 2>, loadLuminanceAlphaDataToBGRA>))); 141 142 return map; 143 } 144 145 static bool GetD3D9FormatInfo(GLenum internalFormat, D3D9FormatInfo *outFormatInfo) 146 { 147 static const D3D9FormatMap formatMap = BuildD3D9FormatMap(); 148 D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat); 149 if (iter != formatMap.end()) 150 { 151 if (outFormatInfo) 152 { 153 *outFormatInfo = iter->second; 154 } 155 return true; 156 } 157 else 158 { 159 return false; 160 } 161 } 162 163 // A map to determine the pixel size and mip generation function of a given D3D format 164 struct D3DFormatInfo 165 { 166 GLuint mPixelBits; 167 GLuint mBlockWidth; 168 GLuint mBlockHeight; 169 GLenum mInternalFormat; 170 171 MipGenerationFunction mMipGenerationFunction; 172 ColorReadFunction mColorReadFunction; 173 174 D3DFormatInfo() 175 : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL), 176 mColorReadFunction(NULL) 177 { } 178 179 D3DFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLenum internalFormat, 180 MipGenerationFunction mipFunc, ColorReadFunction readFunc) 181 : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat), 182 mMipGenerationFunction(mipFunc), mColorReadFunction(readFunc) 183 { } 184 }; 185 186 typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair; 187 typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap; 188 189 static D3D9FormatInfoMap BuildD3D9FormatInfoMap() 190 { 191 D3D9FormatInfoMap map; 192 193 // | D3DFORMAT | | S |W |H | Internal format | Mip generation function | Color read function | 194 map.insert(D3D9FormatInfoPair(D3DFMT_NULL, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); 195 map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL, NULL ))); 196 197 map.insert(D3D9FormatInfoPair(D3DFMT_L8, D3DFormatInfo( 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ))); 198 map.insert(D3D9FormatInfoPair(D3DFMT_A8, D3DFormatInfo( 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ))); 199 map.insert(D3D9FormatInfoPair(D3DFMT_A8L8, D3DFormatInfo( 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ))); 200 map.insert(D3D9FormatInfoPair(D3DFMT_A4R4G4B4, D3DFormatInfo( 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> ))); 201 map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5, D3DFormatInfo( 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> ))); 202 map.insert(D3D9FormatInfoPair(D3DFMT_R5G6B5, D3DFormatInfo( 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ))); 203 map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ))); 204 map.insert(D3D9FormatInfoPair(D3DFMT_A8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ))); 205 map.insert(D3D9FormatInfoPair(D3DFMT_R16F, D3DFormatInfo( 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> ))); 206 map.insert(D3D9FormatInfoPair(D3DFMT_G16R16F, D3DFormatInfo( 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> ))); 207 map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>))); 208 map.insert(D3D9FormatInfoPair(D3DFMT_R32F, D3DFormatInfo( 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> ))); 209 map.insert(D3D9FormatInfoPair(D3DFMT_G32R32F, D3DFormatInfo( 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> ))); 210 map.insert(D3D9FormatInfoPair(D3DFMT_A32B32G32R32F, D3DFormatInfo(128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>))); 211 212 map.insert(D3D9FormatInfoPair(D3DFMT_D16, D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); 213 map.insert(D3D9FormatInfoPair(D3DFMT_D24S8, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); 214 map.insert(D3D9FormatInfoPair(D3DFMT_D24X8, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL ))); 215 map.insert(D3D9FormatInfoPair(D3DFMT_D32, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL ))); 216 217 map.insert(D3D9FormatInfoPair(D3DFMT_INTZ, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL ))); 218 219 map.insert(D3D9FormatInfoPair(D3DFMT_DXT1, D3DFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ))); 220 map.insert(D3D9FormatInfoPair(D3DFMT_DXT3, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ))); 221 map.insert(D3D9FormatInfoPair(D3DFMT_DXT5, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ))); 222 223 return map; 224 } 225 226 static const D3D9FormatInfoMap &GetD3D9FormatInfoMap() 227 { 228 static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); 229 return infoMap; 230 } 231 232 static bool GetD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo) 233 { 234 const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap(); 235 D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); 236 if (iter != infoMap.end()) 237 { 238 if (outFormatInfo) 239 { 240 *outFormatInfo = iter->second; 241 } 242 return true; 243 } 244 else 245 { 246 return false; 247 } 248 } 249 static d3d9::D3DFormatSet BuildAllD3DFormatSet() 250 { 251 d3d9::D3DFormatSet set; 252 253 const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap(); 254 for (D3D9FormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i) 255 { 256 set.insert(i->first); 257 } 258 259 return set; 260 } 261 262 struct D3D9FastCopyFormat 263 { 264 D3DFORMAT mSourceFormat; 265 GLenum mDestFormat; 266 GLenum mDestType; 267 268 D3D9FastCopyFormat(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType) 269 : mSourceFormat(sourceFormat), mDestFormat(destFormat), mDestType(destType) 270 { } 271 272 bool operator<(const D3D9FastCopyFormat& other) const 273 { 274 return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; 275 } 276 }; 277 278 typedef std::map<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyMap; 279 typedef std::pair<D3D9FastCopyFormat, ColorCopyFunction> D3D9FastCopyPair; 280 281 static D3D9FastCopyMap BuildFastCopyMap() 282 { 283 D3D9FastCopyMap map; 284 285 map.insert(D3D9FastCopyPair(D3D9FastCopyFormat(D3DFMT_A8R8G8B8, GL_RGBA, GL_UNSIGNED_BYTE), CopyBGRAUByteToRGBAUByte)); 286 287 return map; 288 } 289 290 typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair; 291 typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap; 292 293 static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() 294 { 295 InternalFormatInitialzerMap map; 296 297 map.insert(InternalFormatInitialzerPair(GL_RGB16F, initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>)); 298 map.insert(InternalFormatInitialzerPair(GL_RGB32F, initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>)); 299 300 return map; 301 } 302 303 static const InternalFormatInitialzerMap &GetInternalFormatInitialzerMap() 304 { 305 static const InternalFormatInitialzerMap map = BuildInternalFormatInitialzerMap(); 306 return map; 307 } 308 309 namespace d3d9 310 { 311 312 MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format) 313 { 314 D3DFormatInfo d3dFormatInfo; 315 if (GetD3D9FormatInfo(format, &d3dFormatInfo)) 316 { 317 return d3dFormatInfo.mMipGenerationFunction; 318 } 319 else 320 { 321 UNREACHABLE(); 322 return NULL; 323 } 324 } 325 326 LoadImageFunction GetImageLoadFunction(GLenum internalFormat, const Renderer9 *renderer) 327 { 328 if (!renderer) 329 { 330 return NULL; 331 } 332 333 ASSERT(renderer->getCurrentClientVersion() == 2); 334 335 D3D9FormatInfo d3d9FormatInfo; 336 if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) 337 { 338 return d3d9FormatInfo.mLoadFunction(renderer); 339 } 340 else 341 { 342 UNREACHABLE(); 343 return NULL; 344 } 345 } 346 347 GLuint GetFormatPixelBytes(D3DFORMAT format) 348 { 349 D3DFormatInfo d3dFormatInfo; 350 if (GetD3D9FormatInfo(format, &d3dFormatInfo)) 351 { 352 return d3dFormatInfo.mPixelBits / 8; 353 } 354 else 355 { 356 UNREACHABLE(); 357 return 0; 358 } 359 } 360 361 GLuint GetBlockWidth(D3DFORMAT format) 362 { 363 D3DFormatInfo d3dFormatInfo; 364 if (GetD3D9FormatInfo(format, &d3dFormatInfo)) 365 { 366 return d3dFormatInfo.mBlockWidth; 367 } 368 else 369 { 370 UNREACHABLE(); 371 return 0; 372 } 373 } 374 375 GLuint GetBlockHeight(D3DFORMAT format) 376 { 377 D3DFormatInfo d3dFormatInfo; 378 if (GetD3D9FormatInfo(format, &d3dFormatInfo)) 379 { 380 return d3dFormatInfo.mBlockHeight; 381 } 382 else 383 { 384 UNREACHABLE(); 385 return 0; 386 } 387 } 388 389 GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height) 390 { 391 D3DFormatInfo d3dFormatInfo; 392 if (GetD3D9FormatInfo(format, &d3dFormatInfo)) 393 { 394 GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth; 395 GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight; 396 397 return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8; 398 } 399 else 400 { 401 UNREACHABLE(); 402 return 0; 403 } 404 } 405 406 void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) 407 { 408 D3DFormatInfo d3dFormatInfo; 409 if (GetD3D9FormatInfo(format, &d3dFormatInfo)) 410 { 411 int upsampleCount = 0; 412 413 GLsizei blockWidth = d3dFormatInfo.mBlockWidth; 414 GLsizei blockHeight = d3dFormatInfo.mBlockHeight; 415 416 // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. 417 if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight) 418 { 419 while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0) 420 { 421 *requestWidth <<= 1; 422 *requestHeight <<= 1; 423 upsampleCount++; 424 } 425 } 426 *levelOffset = upsampleCount; 427 } 428 } 429 430 const D3DFormatSet &GetAllUsedD3DFormats() 431 { 432 static const D3DFormatSet formatSet = BuildAllD3DFormatSet(); 433 return formatSet; 434 } 435 436 ColorReadFunction GetColorReadFunction(D3DFORMAT format) 437 { 438 D3DFormatInfo d3dFormatInfo; 439 if (GetD3D9FormatInfo(format, &d3dFormatInfo)) 440 { 441 return d3dFormatInfo.mColorReadFunction; 442 } 443 else 444 { 445 UNREACHABLE(); 446 return NULL; 447 } 448 } 449 450 ColorCopyFunction GetFastCopyFunction(D3DFORMAT sourceFormat, GLenum destFormat, GLenum destType, GLuint clientVersion) 451 { 452 static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap(); 453 D3D9FastCopyMap::const_iterator iter = fastCopyMap.find(D3D9FastCopyFormat(sourceFormat, destFormat, destType)); 454 return (iter != fastCopyMap.end()) ? iter->second : NULL; 455 } 456 457 GLenum GetDeclTypeComponentType(D3DDECLTYPE declType) 458 { 459 switch (declType) 460 { 461 case D3DDECLTYPE_FLOAT1: return GL_FLOAT; 462 case D3DDECLTYPE_FLOAT2: return GL_FLOAT; 463 case D3DDECLTYPE_FLOAT3: return GL_FLOAT; 464 case D3DDECLTYPE_FLOAT4: return GL_FLOAT; 465 case D3DDECLTYPE_UBYTE4: return GL_UNSIGNED_INT; 466 case D3DDECLTYPE_SHORT2: return GL_INT; 467 case D3DDECLTYPE_SHORT4: return GL_INT; 468 case D3DDECLTYPE_UBYTE4N: return GL_UNSIGNED_NORMALIZED; 469 case D3DDECLTYPE_SHORT4N: return GL_SIGNED_NORMALIZED; 470 case D3DDECLTYPE_USHORT4N: return GL_UNSIGNED_NORMALIZED; 471 case D3DDECLTYPE_SHORT2N: return GL_SIGNED_NORMALIZED; 472 case D3DDECLTYPE_USHORT2N: return GL_UNSIGNED_NORMALIZED; 473 default: UNREACHABLE(); return GL_NONE; 474 } 475 } 476 477 // Attribute format conversion 478 enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; 479 480 struct FormatConverter 481 { 482 bool identity; 483 std::size_t outputElementSize; 484 void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); 485 D3DDECLTYPE d3dDeclType; 486 }; 487 488 struct TranslationDescription 489 { 490 DWORD capsFlag; 491 FormatConverter preferredConversion; 492 FormatConverter fallbackConversion; 493 }; 494 495 static unsigned int typeIndex(GLenum type); 496 static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute); 497 498 bool mTranslationsInitialized = false; 499 FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; 500 501 // Mapping from OpenGL-ES vertex attrib type to D3D decl type: 502 // 503 // BYTE SHORT (Cast) 504 // BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm) 505 // UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast) 506 // UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize) 507 // SHORT SHORT (Identity) 508 // SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize) 509 // UNSIGNED_SHORT FLOAT (Cast) 510 // UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize) 511 // FIXED (not in WebGL) FLOAT (FixedToFloat) 512 // FLOAT FLOAT (Identity) 513 514 // GLToCType maps from GL type (as GLenum) to the C typedef. 515 template <GLenum GLType> struct GLToCType { }; 516 517 template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; }; 518 template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; }; 519 template <> struct GLToCType<GL_SHORT> { typedef GLshort type; }; 520 template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; }; 521 template <> struct GLToCType<GL_FIXED> { typedef GLuint type; }; 522 template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; }; 523 524 // This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.) 525 enum D3DVertexType 526 { 527 D3DVT_FLOAT, 528 D3DVT_SHORT, 529 D3DVT_SHORT_NORM, 530 D3DVT_UBYTE, 531 D3DVT_UBYTE_NORM, 532 D3DVT_USHORT_NORM 533 }; 534 535 // D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type. 536 template <unsigned int D3DType> struct D3DToCType { }; 537 538 template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; }; 539 template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; }; 540 template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; }; 541 template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; }; 542 template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; }; 543 template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; }; 544 545 // Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size. 546 template <unsigned int type, int size> struct WidenRule { }; 547 548 template <int size> struct WidenRule<D3DVT_FLOAT, size> : NoWiden<size> { }; 549 template <int size> struct WidenRule<D3DVT_SHORT, size> : WidenToEven<size> { }; 550 template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : WidenToEven<size> { }; 551 template <int size> struct WidenRule<D3DVT_UBYTE, size> : WidenToFour<size> { }; 552 template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : WidenToFour<size> { }; 553 template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : WidenToEven<size> { }; 554 555 // VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination. 556 template <unsigned int d3dtype, int size> struct VertexTypeFlags { }; 557 558 template <unsigned int _capflag, unsigned int _declflag> 559 struct VertexTypeFlagsHelper 560 { 561 enum { capflag = _capflag }; 562 enum { declflag = _declflag }; 563 }; 564 565 template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { }; 566 template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { }; 567 template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { }; 568 template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { }; 569 template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { }; 570 template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { }; 571 template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { }; 572 template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { }; 573 template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { }; 574 template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { }; 575 template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { }; 576 template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { }; 577 578 579 // VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums). 580 template <GLenum GLtype, bool normalized> struct VertexTypeMapping { }; 581 582 template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred> 583 struct VertexTypeMappingBase 584 { 585 enum { preferred = Preferred }; 586 enum { fallback = Fallback }; 587 }; 588 589 template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast 590 template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize 591 template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast 592 template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize 593 template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity 594 template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize 595 template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast 596 template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize 597 template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat 598 template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity 599 600 601 // Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat). 602 // The conversion rules themselves are defined in vertexconversion.h. 603 604 // Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping). 605 template <GLenum fromType, bool normalized, unsigned int toType> 606 struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> { }; 607 608 // All conversions from normalized types to float use the Normalize operator. 609 template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type> { }; 610 611 // Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules. 612 template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { }; 613 template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { }; 614 615 // A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1) 616 // whether it is normalized or not. 617 template <class T, bool normalized> struct DefaultVertexValuesStage2 { }; 618 619 template <class T> struct DefaultVertexValuesStage2<T, true> : NormalizedDefaultValues<T> { }; 620 template <class T> struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T> { }; 621 622 // Work out the default value rule for a D3D type (expressed as the C type) and 623 template <class T, bool normalized> struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized> { }; 624 template <bool normalized> struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float> { }; 625 626 // Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion. 627 // The fallback conversion produces an output that all D3D9 devices must support. 628 template <class T> struct UsePreferred { enum { type = T::preferred }; }; 629 template <class T> struct UseFallback { enum { type = T::fallback }; }; 630 631 // Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion, 632 // it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag 633 // and the D3DDECLTYPE member needed for the vertex declaration in declflag. 634 template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule> 635 struct Converter 636 : VertexDataConverter<typename GLToCType<fromType>::type, 637 WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>, 638 ConversionRule<fromType, 639 normalized, 640 PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>, 641 DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > > 642 { 643 private: 644 enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type }; 645 enum { d3dsize = WidenRule<d3dtype, size>::finalWidth }; 646 647 public: 648 enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag }; 649 enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag }; 650 }; 651 652 // Initialize a TranslationInfo 653 #define TRANSLATION(type, norm, size, preferred) \ 654 { \ 655 Converter<type, norm, size, preferred>::identity, \ 656 Converter<type, norm, size, preferred>::finalSize, \ 657 Converter<type, norm, size, preferred>::convertArray, \ 658 static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \ 659 } 660 661 #define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ 662 { \ 663 Converter<type, norm, size, UsePreferred>::capflag, \ 664 TRANSLATION(type, norm, size, UsePreferred), \ 665 TRANSLATION(type, norm, size, UseFallback) \ 666 } 667 668 #define TRANSLATIONS_FOR_TYPE(type) \ 669 { \ 670 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ 671 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \ 672 } 673 674 #define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \ 675 { \ 676 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ 677 { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ 678 } 679 680 const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] 681 { 682 TRANSLATIONS_FOR_TYPE(GL_BYTE), 683 TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), 684 TRANSLATIONS_FOR_TYPE(GL_SHORT), 685 TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), 686 TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), 687 TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) 688 }; 689 690 void InitializeVertexTranslations(const rx::Renderer9 *renderer) 691 { 692 DWORD declTypes = renderer->getCapsDeclTypes(); 693 694 for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) 695 { 696 for (unsigned int j = 0; j < 2; j++) 697 { 698 for (unsigned int k = 0; k < 4; k++) 699 { 700 if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) 701 { 702 mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; 703 } 704 else 705 { 706 mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; 707 } 708 } 709 } 710 } 711 } 712 713 unsigned int typeIndex(GLenum type) 714 { 715 switch (type) 716 { 717 case GL_BYTE: return 0; 718 case GL_UNSIGNED_BYTE: return 1; 719 case GL_SHORT: return 2; 720 case GL_UNSIGNED_SHORT: return 3; 721 case GL_FIXED: return 4; 722 case GL_FLOAT: return 5; 723 724 default: UNREACHABLE(); return 5; 725 } 726 } 727 728 const FormatConverter &formatConverter(const gl::VertexFormat &vertexFormat) 729 { 730 // Pure integer attributes only supported in ES3.0 731 ASSERT(!vertexFormat.mPureInteger); 732 return mFormatConverters[typeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; 733 } 734 735 VertexCopyFunction GetVertexCopyFunction(const gl::VertexFormat &vertexFormat) 736 { 737 return formatConverter(vertexFormat).convertArray; 738 } 739 740 size_t GetVertexElementSize(const gl::VertexFormat &vertexFormat) 741 { 742 return formatConverter(vertexFormat).outputElementSize; 743 } 744 745 VertexConversionType GetVertexConversionType(const gl::VertexFormat &vertexFormat) 746 { 747 return (formatConverter(vertexFormat).identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU); 748 } 749 750 D3DDECLTYPE GetNativeVertexFormat(const gl::VertexFormat &vertexFormat) 751 { 752 return formatConverter(vertexFormat).d3dDeclType; 753 } 754 755 } 756 757 namespace gl_d3d9 758 { 759 760 D3DFORMAT GetTextureFormat(GLenum internalFormat, const Renderer9 *renderer) 761 { 762 if (!renderer) 763 { 764 UNREACHABLE(); 765 return D3DFMT_UNKNOWN; 766 } 767 768 ASSERT(renderer->getCurrentClientVersion() == 2); 769 770 D3D9FormatInfo d3d9FormatInfo; 771 if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) 772 { 773 return d3d9FormatInfo.mTexFormat(renderer); 774 } 775 else 776 { 777 UNREACHABLE(); 778 return D3DFMT_UNKNOWN; 779 } 780 } 781 782 D3DFORMAT GetRenderFormat(GLenum internalFormat, const Renderer9 *renderer) 783 { 784 if (!renderer) 785 { 786 UNREACHABLE(); 787 return D3DFMT_UNKNOWN; 788 } 789 790 ASSERT(renderer->getCurrentClientVersion() == 2); 791 792 D3D9FormatInfo d3d9FormatInfo; 793 if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo)) 794 { 795 return d3d9FormatInfo.mRenderFormat(renderer); 796 } 797 else 798 { 799 UNREACHABLE(); 800 return D3DFMT_UNKNOWN; 801 } 802 } 803 804 D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples) 805 { 806 return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE; 807 } 808 809 bool RequiresTextureDataInitialization(GLint internalFormat) 810 { 811 const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap(); 812 return map.find(internalFormat) != map.end(); 813 } 814 815 InitializeTextureDataFunction GetTextureDataInitializationFunction(GLint internalFormat) 816 { 817 const InternalFormatInitialzerMap &map = GetInternalFormatInitialzerMap(); 818 InternalFormatInitialzerMap::const_iterator iter = map.find(internalFormat); 819 if (iter != map.end()) 820 { 821 return iter->second; 822 } 823 else 824 { 825 UNREACHABLE(); 826 return NULL; 827 } 828 } 829 830 } 831 832 namespace d3d9_gl 833 { 834 835 GLenum GetInternalFormat(D3DFORMAT format) 836 { 837 static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); 838 D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); 839 if (iter != infoMap.end()) 840 { 841 return iter->second.mInternalFormat; 842 } 843 else 844 { 845 UNREACHABLE(); 846 return GL_NONE; 847 } 848 } 849 850 GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) 851 { 852 return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; 853 } 854 855 bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion) 856 { 857 GLenum internalFormat = d3d9_gl::GetInternalFormat(d3dformat); 858 GLenum convertedFormat = gl::GetFormat(internalFormat, clientVersion); 859 return convertedFormat == format; 860 } 861 862 } 863 864 } 865