tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

formatutils9.cpp (27413B)


      1 //
      2 // Copyright 2013 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 
      7 // formatutils9.cpp: Queries for GL image formats and their translations to D3D9
      8 // formats.
      9 
     10 #include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
     11 
     12 #include "image_util/copyimage.h"
     13 #include "image_util/generatemip.h"
     14 #include "image_util/loadimage.h"
     15 
     16 #include "anglebase/no_destructor.h"
     17 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
     18 #include "libANGLE/renderer/d3d/d3d9/vertexconversion.h"
     19 
     20 using namespace angle;
     21 
     22 namespace rx
     23 {
     24 
     25 namespace d3d9
     26 {
     27 
     28 constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')));
     29 constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L')));
     30 
     31 // A map to determine the pixel size and mip generation function of a given D3D format
     32 typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap;
     33 
     34 typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair;
     35 typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap;
     36 
     37 static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap()
     38 {
     39    using namespace angle;  // For image initialization functions
     40 
     41    InternalFormatInitialzerMap map;
     42 
     43    map.insert(InternalFormatInitialzerPair(
     44        GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>));
     45    map.insert(InternalFormatInitialzerPair(
     46        GL_RGB32F,
     47        Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
     48 
     49    return map;
     50 }
     51 
     52 static void UnreachableLoad(size_t width,
     53                            size_t height,
     54                            size_t depth,
     55                            const uint8_t *input,
     56                            size_t inputRowPitch,
     57                            size_t inputDepthPitch,
     58                            uint8_t *output,
     59                            size_t outputRowPitch,
     60                            size_t outputDepthPitch)
     61 {
     62    UNREACHABLE();
     63 }
     64 
     65 typedef std::pair<GLenum, TextureFormat> D3D9FormatPair;
     66 typedef std::map<GLenum, TextureFormat> D3D9FormatMap;
     67 
     68 TextureFormat::TextureFormat()
     69    : texFormat(D3DFMT_UNKNOWN),
     70      renderFormat(D3DFMT_UNKNOWN),
     71      dataInitializerFunction(nullptr),
     72      loadFunction(UnreachableLoad)
     73 {}
     74 
     75 static inline void InsertD3D9FormatInfo(D3D9FormatMap *map,
     76                                        GLenum internalFormat,
     77                                        D3DFORMAT texFormat,
     78                                        D3DFORMAT renderFormat,
     79                                        LoadImageFunction loadFunction)
     80 {
     81    TextureFormat info;
     82    info.texFormat    = texFormat;
     83    info.renderFormat = renderFormat;
     84 
     85    static const angle::base::NoDestructor<InternalFormatInitialzerMap> dataInitializationMap(
     86        BuildInternalFormatInitialzerMap());
     87    InternalFormatInitialzerMap::const_iterator dataInitIter =
     88        dataInitializationMap->find(internalFormat);
     89    info.dataInitializerFunction =
     90        (dataInitIter != dataInitializationMap->end()) ? dataInitIter->second : nullptr;
     91 
     92    info.loadFunction = loadFunction;
     93 
     94    map->insert(std::make_pair(internalFormat, info));
     95 }
     96 
     97 static D3D9FormatMap BuildD3D9FormatMap()
     98 {
     99    using namespace angle;  // For image loading functions
    100 
    101    D3D9FormatMap map;
    102 
    103    // clang-format off
    104    //                       | Internal format                     | Texture format      | Render format        | Load function                           |
    105    InsertD3D9FormatInfo(&map, GL_NONE,                             D3DFMT_NULL,          D3DFMT_NULL,           UnreachableLoad                          );
    106 
    107    // We choose to downsample the GL_DEPTH_COMPONENT32_OES format to a 24-bit format because D3DFMT_D32 is not widely
    108    // supported.  We're allowed to do this because:
    109    //  - The ES spec 2.0.25 sec 3.7.1 states that we're allowed to store texture formats with internal format
    110    //    resolutions of our own choosing.
    111    //  - OES_depth_texture states that downsampling of the depth formats is allowed.
    112    //  - ANGLE_depth_texture does not state minimum required resolutions of the depth texture formats it
    113    //    introduces.
    114    // In ES3 however, there are minimum resolutions for the texture formats and this would not be allowed.
    115 
    116    InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT16,                D3DFMT_INTZ,          D3DFMT_D24S8,          UnreachableLoad                          );
    117    InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES,            D3DFMT_INTZ,          D3DFMT_D24X8,          UnreachableLoad                          );
    118    InsertD3D9FormatInfo(&map, GL_DEPTH24_STENCIL8_OES,             D3DFMT_INTZ,          D3DFMT_D24S8,          UnreachableLoad                          );
    119    InsertD3D9FormatInfo(&map, GL_STENCIL_INDEX8,                   D3DFMT_UNKNOWN,       D3DFMT_D24S8,          UnreachableLoad                          ); // TODO: What's the texture format?
    120 
    121    InsertD3D9FormatInfo(&map, GL_RGBA32F_EXT,                      D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F,  LoadToNative<GLfloat, 4>                 );
    122    InsertD3D9FormatInfo(&map, GL_RGB32F_EXT,                       D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F,  LoadToNative3To4<GLfloat, gl::Float32One>);
    123    InsertD3D9FormatInfo(&map, GL_RG32F_EXT,                        D3DFMT_G32R32F,       D3DFMT_G32R32F,        LoadToNative<GLfloat, 2>                 );
    124    InsertD3D9FormatInfo(&map, GL_R32F_EXT,                         D3DFMT_R32F,          D3DFMT_R32F,           LoadToNative<GLfloat, 1>                 );
    125    InsertD3D9FormatInfo(&map, GL_ALPHA32F_EXT,                     D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN,        LoadA32FToRGBA32F                        );
    126    InsertD3D9FormatInfo(&map, GL_LUMINANCE32F_EXT,                 D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN,        LoadL32FToRGBA32F                        );
    127    InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT,           D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN,        LoadLA32FToRGBA32F                       );
    128 
    129    InsertD3D9FormatInfo(&map, GL_RGBA16F_EXT,                      D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F,  LoadToNative<GLhalf, 4>                  );
    130    InsertD3D9FormatInfo(&map, GL_RGB16F_EXT,                       D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F,  LoadToNative3To4<GLhalf, gl::Float16One> );
    131    InsertD3D9FormatInfo(&map, GL_RG16F_EXT,                        D3DFMT_G16R16F,       D3DFMT_G16R16F,        LoadToNative<GLhalf, 2>                  );
    132    InsertD3D9FormatInfo(&map, GL_R16F_EXT,                         D3DFMT_R16F,          D3DFMT_R16F,           LoadToNative<GLhalf, 1>                  );
    133    InsertD3D9FormatInfo(&map, GL_ALPHA16F_EXT,                     D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN,        LoadA16FToRGBA16F                        );
    134    InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT,                 D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN,        LoadL16FToRGBA16F                        );
    135    InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT,           D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN,        LoadLA16FToRGBA16F                       );
    136 
    137    InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT,                       D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadA8ToBGRA8                            );
    138 
    139    InsertD3D9FormatInfo(&map, GL_RGB8_OES,                         D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadRGB8ToBGRX8                           );
    140    InsertD3D9FormatInfo(&map, GL_RGB565,                           D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadR5G6B5ToBGRA8                         );
    141    InsertD3D9FormatInfo(&map, GL_RGBA8_OES,                        D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadRGBA8ToBGRA8                          );
    142    InsertD3D9FormatInfo(&map, GL_RGBA4,                            D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadRGBA4ToBGRA8                          );
    143    InsertD3D9FormatInfo(&map, GL_RGB5_A1,                          D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadRGB5A1ToBGRA8                         );
    144    InsertD3D9FormatInfo(&map, GL_R8_EXT,                           D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadR8ToBGRX8                             );
    145    InsertD3D9FormatInfo(&map, GL_RG8_EXT,                          D3DFMT_X8R8G8B8,      D3DFMT_X8R8G8B8,       LoadRG8ToBGRX8                            );
    146 
    147    InsertD3D9FormatInfo(&map, GL_SRGB8,                            D3DFMT_X8R8G8B8,      D3DFMT_UNKNOWN,        LoadRGB8ToBGRX8                           );
    148    InsertD3D9FormatInfo(&map, GL_SRGB8_ALPHA8_EXT,                 D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadRGBA8ToBGRA8                          );
    149 
    150    InsertD3D9FormatInfo(&map, GL_BGRA8_EXT,                        D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadToNative<GLubyte, 4>                  );
    151    InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX,                     D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadBGRA4ToBGRA8                          );
    152    InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX,                   D3DFMT_A8R8G8B8,      D3DFMT_A8R8G8B8,       LoadBGR5A1ToBGRA8                         );
    153 
    154    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,     D3DFMT_DXT1,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1,  8>       );
    155    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,    D3DFMT_DXT1,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1,  8>       );
    156    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,  D3DFMT_DXT3,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1, 16>       );
    157    InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,  D3DFMT_DXT5,          D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1, 16>       );
    158 
    159    InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,        D3DFMT_DXT1,      D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1,  8>       );
    160    InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,  D3DFMT_DXT1,      D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1,  8>       );
    161    InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,  D3DFMT_DXT3,      D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1, 16>       );
    162    InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,  D3DFMT_DXT5,      D3DFMT_UNKNOWN,        LoadCompressedToNative<4, 4, 1, 16>       );
    163 
    164    // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
    165    // then changing the format and loading function appropriately.
    166    InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT,                   D3DFMT_L8,            D3DFMT_UNKNOWN,        LoadToNative<GLubyte, 1>                  );
    167    InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT,            D3DFMT_A8L8,          D3DFMT_UNKNOWN,        LoadToNative<GLubyte, 2>                  );
    168    // clang-format on
    169 
    170    return map;
    171 }
    172 
    173 const TextureFormat &GetTextureFormatInfo(GLenum internalFormat)
    174 {
    175    static const angle::base::NoDestructor<D3D9FormatMap> formatMap(BuildD3D9FormatMap());
    176    D3D9FormatMap::const_iterator iter = formatMap->find(internalFormat);
    177    if (iter != formatMap->end())
    178    {
    179        return iter->second;
    180    }
    181    else
    182    {
    183        static const TextureFormat defaultInfo;
    184        return defaultInfo;
    185    }
    186 }
    187 
    188 static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
    189 {
    190    switch (declType)
    191    {
    192        case D3DDECLTYPE_FLOAT1:
    193            return GL_FLOAT;
    194        case D3DDECLTYPE_FLOAT2:
    195            return GL_FLOAT;
    196        case D3DDECLTYPE_FLOAT3:
    197            return GL_FLOAT;
    198        case D3DDECLTYPE_FLOAT4:
    199            return GL_FLOAT;
    200        case D3DDECLTYPE_UBYTE4:
    201            return GL_UNSIGNED_INT;
    202        case D3DDECLTYPE_SHORT2:
    203            return GL_INT;
    204        case D3DDECLTYPE_SHORT4:
    205            return GL_INT;
    206        case D3DDECLTYPE_UBYTE4N:
    207            return GL_UNSIGNED_NORMALIZED;
    208        case D3DDECLTYPE_SHORT4N:
    209            return GL_SIGNED_NORMALIZED;
    210        case D3DDECLTYPE_USHORT4N:
    211            return GL_UNSIGNED_NORMALIZED;
    212        case D3DDECLTYPE_SHORT2N:
    213            return GL_SIGNED_NORMALIZED;
    214        case D3DDECLTYPE_USHORT2N:
    215            return GL_UNSIGNED_NORMALIZED;
    216        default:
    217            UNREACHABLE();
    218            return GL_NONE;
    219    }
    220 }
    221 
    222 // Attribute format conversion
    223 enum
    224 {
    225    NUM_GL_VERTEX_ATTRIB_TYPES = 6
    226 };
    227 
    228 struct TranslationDescription
    229 {
    230    DWORD capsFlag;
    231    VertexFormat preferredConversion;
    232    VertexFormat fallbackConversion;
    233 };
    234 
    235 // Mapping from OpenGL-ES vertex attrib type to D3D decl type:
    236 //
    237 // BYTE                 SHORT (Cast)
    238 // BYTE-norm            FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
    239 // UNSIGNED_BYTE        UBYTE4 (Identity) or SHORT (Cast)
    240 // UNSIGNED_BYTE-norm   UBYTE4N (Identity) or FLOAT (Normalize)
    241 // SHORT                SHORT (Identity)
    242 // SHORT-norm           SHORT-norm (Identity) or FLOAT (Normalize)
    243 // UNSIGNED_SHORT       FLOAT (Cast)
    244 // UNSIGNED_SHORT-norm  USHORT-norm (Identity) or FLOAT (Normalize)
    245 // FIXED (not in WebGL) FLOAT (FixedToFloat)
    246 // FLOAT                FLOAT (Identity)
    247 
    248 // GLToCType maps from GL type (as GLenum) to the C typedef.
    249 template <GLenum GLType>
    250 struct GLToCType
    251 {};
    252 
    253 template <>
    254 struct GLToCType<GL_BYTE>
    255 {
    256    typedef GLbyte type;
    257 };
    258 template <>
    259 struct GLToCType<GL_UNSIGNED_BYTE>
    260 {
    261    typedef GLubyte type;
    262 };
    263 template <>
    264 struct GLToCType<GL_SHORT>
    265 {
    266    typedef GLshort type;
    267 };
    268 template <>
    269 struct GLToCType<GL_UNSIGNED_SHORT>
    270 {
    271    typedef GLushort type;
    272 };
    273 template <>
    274 struct GLToCType<GL_FIXED>
    275 {
    276    typedef GLuint type;
    277 };
    278 template <>
    279 struct GLToCType<GL_FLOAT>
    280 {
    281    typedef GLfloat type;
    282 };
    283 
    284 // This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
    285 enum D3DVertexType
    286 {
    287    D3DVT_FLOAT,
    288    D3DVT_SHORT,
    289    D3DVT_SHORT_NORM,
    290    D3DVT_UBYTE,
    291    D3DVT_UBYTE_NORM,
    292    D3DVT_USHORT_NORM
    293 };
    294 
    295 // D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
    296 template <unsigned int D3DType>
    297 struct D3DToCType
    298 {};
    299 
    300 template <>
    301 struct D3DToCType<D3DVT_FLOAT>
    302 {
    303    typedef float type;
    304 };
    305 template <>
    306 struct D3DToCType<D3DVT_SHORT>
    307 {
    308    typedef short type;
    309 };
    310 template <>
    311 struct D3DToCType<D3DVT_SHORT_NORM>
    312 {
    313    typedef short type;
    314 };
    315 template <>
    316 struct D3DToCType<D3DVT_UBYTE>
    317 {
    318    typedef unsigned char type;
    319 };
    320 template <>
    321 struct D3DToCType<D3DVT_UBYTE_NORM>
    322 {
    323    typedef unsigned char type;
    324 };
    325 template <>
    326 struct D3DToCType<D3DVT_USHORT_NORM>
    327 {
    328    typedef unsigned short type;
    329 };
    330 
    331 // Encode the type/size combinations that D3D permits. For each type/size it expands to a widener
    332 // that will provide the appropriate final size.
    333 template <unsigned int type, int size>
    334 struct WidenRule
    335 {};
    336 
    337 template <int size>
    338 struct WidenRule<D3DVT_FLOAT, size> : NoWiden<size>
    339 {};
    340 template <int size>
    341 struct WidenRule<D3DVT_SHORT, size> : WidenToEven<size>
    342 {};
    343 template <int size>
    344 struct WidenRule<D3DVT_SHORT_NORM, size> : WidenToEven<size>
    345 {};
    346 template <int size>
    347 struct WidenRule<D3DVT_UBYTE, size> : WidenToFour<size>
    348 {};
    349 template <int size>
    350 struct WidenRule<D3DVT_UBYTE_NORM, size> : WidenToFour<size>
    351 {};
    352 template <int size>
    353 struct WidenRule<D3DVT_USHORT_NORM, size> : WidenToEven<size>
    354 {};
    355 
    356 // VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D
    357 // vertex type & size combination.
    358 template <unsigned int d3dtype, int size>
    359 struct VertexTypeFlags
    360 {};
    361 
    362 template <unsigned int _capflag, unsigned int _declflag>
    363 struct VertexTypeFlagsHelper
    364 {
    365    enum
    366    {
    367        capflag = _capflag
    368    };
    369    enum
    370    {
    371        declflag = _declflag
    372    };
    373 };
    374 
    375 template <>
    376 struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1>
    377 {};
    378 template <>
    379 struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2>
    380 {};
    381 template <>
    382 struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3>
    383 {};
    384 template <>
    385 struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4>
    386 {};
    387 template <>
    388 struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2>
    389 {};
    390 template <>
    391 struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4>
    392 {};
    393 template <>
    394 struct VertexTypeFlags<D3DVT_SHORT_NORM, 2>
    395    : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N>
    396 {};
    397 template <>
    398 struct VertexTypeFlags<D3DVT_SHORT_NORM, 4>
    399    : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N>
    400 {};
    401 template <>
    402 struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4>
    403 {};
    404 template <>
    405 struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4>
    406    : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N>
    407 {};
    408 template <>
    409 struct VertexTypeFlags<D3DVT_USHORT_NORM, 2>
    410    : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N>
    411 {};
    412 template <>
    413 struct VertexTypeFlags<D3DVT_USHORT_NORM, 4>
    414    : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N>
    415 {};
    416 
    417 // VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as
    418 // D3DVertexType enums).
    419 template <GLenum GLtype, bool normalized>
    420 struct VertexTypeMapping
    421 {};
    422 
    423 template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
    424 struct VertexTypeMappingBase
    425 {
    426    enum
    427    {
    428        preferred = Preferred
    429    };
    430    enum
    431    {
    432        fallback = Fallback
    433    };
    434 };
    435 
    436 template <>
    437 struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT>
    438 {};  // Cast
    439 template <>
    440 struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT>
    441 {};  // Normalize
    442 template <>
    443 struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT>
    444 {};  // Identity, Cast
    445 template <>
    446 struct VertexTypeMapping<GL_UNSIGNED_BYTE, true>
    447    : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT>
    448 {};  // Identity, Normalize
    449 template <>
    450 struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT>
    451 {};  // Identity
    452 template <>
    453 struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT>
    454 {};  // Cast, Normalize
    455 template <>
    456 struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT>
    457 {};  // Cast
    458 template <>
    459 struct VertexTypeMapping<GL_UNSIGNED_SHORT, true>
    460    : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT>
    461 {};  // Cast, Normalize
    462 template <bool normalized>
    463 struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT>
    464 {};  // FixedToFloat
    465 template <bool normalized>
    466 struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT>
    467 {};  // Identity
    468 
    469 // Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule
    470 // (Cast, Normalize, Identity, FixedToFloat). The conversion rules themselves are defined in
    471 // vertexconversion.h.
    472 
    473 // Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T>
    474 // knows it's an identity mapping).
    475 template <GLenum fromType, bool normalized, unsigned int toType>
    476 struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type>
    477 {};
    478 
    479 // All conversions from normalized types to float use the Normalize operator.
    480 template <GLenum fromType>
    481 struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type>
    482 {};
    483 
    484 // Use a full specialization for this so that it preferentially matches ahead of the generic
    485 // normalize-to-float rules.
    486 template <>
    487 struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : FixedToFloat<GLint, 16>
    488 {};
    489 template <>
    490 struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16>
    491 {};
    492 
    493 // A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues
    494 // (i.e. 0/1) whether it is normalized or not.
    495 template <class T, bool normalized>
    496 struct DefaultVertexValuesStage2
    497 {};
    498 
    499 template <class T>
    500 struct DefaultVertexValuesStage2<T, true> : NormalizedDefaultValues<T>
    501 {};
    502 template <class T>
    503 struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T>
    504 {};
    505 
    506 // Work out the default value rule for a D3D type (expressed as the C type) and
    507 template <class T, bool normalized>
    508 struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized>
    509 {};
    510 template <bool normalized>
    511 struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float>
    512 {};
    513 
    514 // Policy rules for use with Converter, to choose whether to use the preferred or fallback
    515 // conversion. The fallback conversion produces an output that all D3D9 devices must support.
    516 template <class T>
    517 struct UsePreferred
    518 {
    519    enum
    520    {
    521        type = T::preferred
    522    };
    523 };
    524 template <class T>
    525 struct UseFallback
    526 {
    527    enum
    528    {
    529        type = T::fallback
    530    };
    531 };
    532 
    533 // Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback
    534 // conversion, it provides all the members of the appropriate VertexDataConverter, the
    535 // D3DCAPS9::DeclTypes flag in cap flag and the D3DDECLTYPE member needed for the vertex declaration
    536 // in declflag.
    537 template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
    538 struct Converter
    539    : VertexDataConverter<
    540          typename GLToCType<fromType>::type,
    541          WidenRule<PreferenceRule<VertexTypeMapping<fromType, normalized>>::type, size>,
    542          ConversionRule<fromType,
    543                         normalized,
    544                         PreferenceRule<VertexTypeMapping<fromType, normalized>>::type>,
    545          DefaultVertexValues<typename D3DToCType<PreferenceRule<
    546                                  VertexTypeMapping<fromType, normalized>>::type>::type,
    547                              normalized>>
    548 {
    549  private:
    550    enum
    551    {
    552        d3dtype = PreferenceRule<VertexTypeMapping<fromType, normalized>>::type
    553    };
    554    enum
    555    {
    556        d3dsize = WidenRule<d3dtype, size>::finalWidth
    557    };
    558 
    559  public:
    560    enum
    561    {
    562        capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag
    563    };
    564    enum
    565    {
    566        declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag
    567    };
    568 };
    569 
    570 VertexFormat::VertexFormat()
    571    : conversionType(VERTEX_CONVERT_NONE),
    572      outputElementSize(0),
    573      copyFunction(nullptr),
    574      nativeFormat(D3DDECLTYPE_UNUSED),
    575      componentType(GL_NONE)
    576 {}
    577 
    578 // Initialize a TranslationInfo
    579 VertexFormat CreateVertexFormatInfo(bool identity,
    580                                    size_t elementSize,
    581                                    VertexCopyFunction copyFunc,
    582                                    D3DDECLTYPE nativeFormat)
    583 {
    584    VertexFormat formatInfo;
    585    formatInfo.conversionType    = identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU;
    586    formatInfo.outputElementSize = elementSize;
    587    formatInfo.copyFunction      = copyFunc;
    588    formatInfo.nativeFormat      = nativeFormat;
    589    formatInfo.componentType     = GetDeclTypeComponentType(nativeFormat);
    590    return formatInfo;
    591 }
    592 
    593 #define TRANSLATION(type, norm, size, preferred)              \
    594    CreateVertexFormatInfo(                                   \
    595        Converter<type, norm, size, preferred>::identity,     \
    596        Converter<type, norm, size, preferred>::finalSize,    \
    597        Converter<type, norm, size, preferred>::convertArray, \
    598        static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag))
    599 
    600 #define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size)    \
    601    {                                                       \
    602        Converter<type, norm, size, UsePreferred>::capflag, \
    603            TRANSLATION(type, norm, size, UsePreferred),    \
    604            TRANSLATION(type, norm, size, UseFallback)      \
    605    }
    606 
    607 #define TRANSLATIONS_FOR_TYPE(type)                          \
    608    {                                                        \
    609        {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1),     \
    610         TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2),     \
    611         TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3),     \
    612         TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)},    \
    613            {TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1),  \
    614             TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2),  \
    615             TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3),  \
    616             TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4)}, \
    617    }
    618 
    619 #define TRANSLATIONS_FOR_TYPE_NO_NORM(type)                   \
    620    {                                                         \
    621        {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1),      \
    622         TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2),      \
    623         TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3),      \
    624         TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)},     \
    625            {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1),  \
    626             TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2),  \
    627             TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3),  \
    628             TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)}, \
    629    }
    630 
    631 static inline unsigned int ComputeTypeIndex(GLenum type)
    632 {
    633    switch (type)
    634    {
    635        case GL_BYTE:
    636            return 0;
    637        case GL_UNSIGNED_BYTE:
    638            return 1;
    639        case GL_SHORT:
    640            return 2;
    641        case GL_UNSIGNED_SHORT:
    642            return 3;
    643        case GL_FIXED:
    644            return 4;
    645        case GL_FLOAT:
    646            return 5;
    647 
    648        default:
    649            UNREACHABLE();
    650            return 5;
    651    }
    652 }
    653 
    654 const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, angle::FormatID vertexFormatID)
    655 {
    656    static DWORD initializedDeclTypes = 0;
    657    static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
    658    if (initializedDeclTypes != supportedDeclTypes)
    659    {
    660        const TranslationDescription
    661            translations[NUM_GL_VERTEX_ATTRIB_TYPES][2]
    662                        [4] =  // [GL types as enumerated by typeIndex()][normalized][size-1]
    663            {TRANSLATIONS_FOR_TYPE(GL_BYTE),          TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
    664             TRANSLATIONS_FOR_TYPE(GL_SHORT),         TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
    665             TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)};
    666        for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
    667        {
    668            for (unsigned int j = 0; j < 2; j++)
    669            {
    670                for (unsigned int k = 0; k < 4; k++)
    671                {
    672                    if (translations[i][j][k].capsFlag == 0 ||
    673                        (supportedDeclTypes & translations[i][j][k].capsFlag) != 0)
    674                    {
    675                        formatConverters[i][j][k] = translations[i][j][k].preferredConversion;
    676                    }
    677                    else
    678                    {
    679                        formatConverters[i][j][k] = translations[i][j][k].fallbackConversion;
    680                    }
    681                }
    682            }
    683        }
    684        initializedDeclTypes = supportedDeclTypes;
    685    }
    686 
    687    const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromID(vertexFormatID);
    688 
    689    // Pure integer attributes only supported in ES3.0
    690    ASSERT(!vertexFormat.pureInteger);
    691    return formatConverters[ComputeTypeIndex(vertexFormat.type)][vertexFormat.normalized]
    692                           [vertexFormat.components - 1];
    693 }
    694 }  // namespace d3d9
    695 }  // namespace rx