Created new helper functions for converting texture formats, loading images and…

Created new helper functions for converting texture formats, loading images and generating mipmaps." TRAC #22972 Signed-off-by: Jamie Madill Signed-off-by: Nicolas Capens Author: Geoff Lang git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2313 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 89200d93
#include "precompiled.h"
//
// Copyright (c) 2013 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.
//
// formatutils.cpp: Queries for GL image formats.
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/mathutil.h"
#include "libGLESv2/renderer/Renderer.h"
namespace gl
{
// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
// format and type combinations.
typedef std::pair<GLenum, GLenum> FormatTypePair;
typedef std::pair<FormatTypePair, GLint> FormatPair;
typedef std::map<FormatTypePair, GLint> FormatMap;
// A helper function to insert data into the D3D11LoadFunctionMap with fewer characters.
static inline void insertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLint internalFormat)
{
map->insert(FormatPair(FormatTypePair(format, type), internalFormat));
}
FormatMap buildES2FormatMap()
{
FormatMap map;
// | Format | Type | Internal format |
insertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT );
insertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT );
insertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT );
insertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT );
insertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT );
insertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT );
insertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT );
insertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT );
insertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT );
insertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8_OES );
insertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565 );
insertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F_EXT );
insertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F_EXT );
insertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8_OES );
insertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4 );
insertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1 );
insertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F_EXT );
insertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F_EXT );
insertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT );
insertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX );
insertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX );
insertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT );
insertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT );
insertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
insertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
insertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16 );
insertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES );
insertFormatMapping(&map, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, GL_DEPTH24_STENCIL8_OES );
return map;
}
static const FormatMap &getES2FormatMap()
{
static const FormatMap es2FormatMap = buildES2FormatMap();
return es2FormatMap;
}
FormatMap buildES3FormatMap()
{
FormatMap map;
// | Format | Type | Internal format |
insertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8 );
insertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4 );
insertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1 );
insertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F );
insertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F );
insertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8 );
insertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565 );
insertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F );
insertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F );
insertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT );
insertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT );
insertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT );
insertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);
insertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT );
insertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT );
insertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);
insertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT );
insertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT );
insertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT );
insertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX );
insertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX );
insertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16 );
insertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT24 );
insertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F );
insertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8 );
insertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8 );
return map;
}
struct FormatInfo
{
GLint mInternalformat;
GLenum mFormat;
GLenum mType;
FormatInfo(GLint internalformat, GLenum format, GLenum type)
: mInternalformat(internalformat), mFormat(format), mType(type) { }
bool operator<(const FormatInfo& other) const
{
return memcmp(this, &other, sizeof(FormatInfo)) < 0;
}
};
// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
typedef std::set<FormatInfo> ES3FormatSet;
ES3FormatSet buildES3FormatSet()
{
ES3FormatSet set;
// Format combinations from ES 3.0.1 spec, table 3.2
// | Internal format | Format | Type |
// | | | |
set.insert(FormatInfo(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGBA8_SNORM, GL_RGBA, GL_BYTE ));
set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ));
set.insert(FormatInfo(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ));
set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ));
set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_RGBA32F, GL_RGBA, GL_FLOAT ));
set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_FLOAT ));
set.insert(FormatInfo(GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE ));
set.insert(FormatInfo(GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT ));
set.insert(FormatInfo(GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT ));
set.insert(FormatInfo(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT ));
set.insert(FormatInfo(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT ));
set.insert(FormatInfo(GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV ));
set.insert(FormatInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGB8_SNORM, GL_RGB, GL_BYTE ));
set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ));
set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV ));
set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV ));
set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_RGB32F, GL_RGB, GL_FLOAT ));
set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_FLOAT ));
set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT ));
set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_FLOAT ));
set.insert(FormatInfo(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGB8I, GL_RGB_INTEGER, GL_BYTE ));
set.insert(FormatInfo(GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT ));
set.insert(FormatInfo(GL_RGB16I, GL_RGB_INTEGER, GL_SHORT ));
set.insert(FormatInfo(GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT ));
set.insert(FormatInfo(GL_RGB32I, GL_RGB_INTEGER, GL_INT ));
set.insert(FormatInfo(GL_RG8, GL_RG, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RG8_SNORM, GL_RG, GL_BYTE ));
set.insert(FormatInfo(GL_RG16F, GL_RG, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_RG32F, GL_RG, GL_FLOAT ));
set.insert(FormatInfo(GL_RG16F, GL_RG, GL_FLOAT ));
set.insert(FormatInfo(GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RG8I, GL_RG_INTEGER, GL_BYTE ));
set.insert(FormatInfo(GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT ));
set.insert(FormatInfo(GL_RG16I, GL_RG_INTEGER, GL_SHORT ));
set.insert(FormatInfo(GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT ));
set.insert(FormatInfo(GL_RG32I, GL_RG_INTEGER, GL_INT ));
set.insert(FormatInfo(GL_R8, GL_RED, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_R8_SNORM, GL_RED, GL_BYTE ));
set.insert(FormatInfo(GL_R16F, GL_RED, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_R32F, GL_RED, GL_FLOAT ));
set.insert(FormatInfo(GL_R16F, GL_RED, GL_FLOAT ));
set.insert(FormatInfo(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_R8I, GL_RED_INTEGER, GL_BYTE ));
set.insert(FormatInfo(GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT ));
set.insert(FormatInfo(GL_R16I, GL_RED_INTEGER, GL_SHORT ));
set.insert(FormatInfo(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT ));
set.insert(FormatInfo(GL_R32I, GL_RED_INTEGER, GL_INT ));
// Unsized formats
set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ));
set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 ));
set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ));
set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE ));
// Depth stencil formats
set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT ));
set.insert(FormatInfo(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ));
set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ));
set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT ));
set.insert(FormatInfo(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 ));
set.insert(FormatInfo(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
// From GL_OES_texture_float
set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT ));
set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT ));
set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_FLOAT ));
// From GL_OES_texture_half_float
set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT ));
// From GL_EXT_texture_storage
// | Internal format | Format | Type |
// | | | |
set.insert(FormatInfo(GL_ALPHA8_EXT, GL_ALPHA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT ));
set.insert(FormatInfo(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT ));
set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT ));
set.insert(FormatInfo(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ));
set.insert(FormatInfo(GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT));
set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT));
set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
// From GL_ANGLE_depth_texture
set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES ));
// Compressed formats
// From ES 3.0.1 spec, table 3.16
// | Internal format | Format | Type |
// | | | |
set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE));
// From GL_EXT_texture_compression_dxt1
set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE));
set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE));
// From GL_ANGLE_texture_compression_dxt3
set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE));
// From GL_ANGLE_texture_compression_dxt5
set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE));
return set;
}
static const ES3FormatSet &getES3FormatSet()
{
static const ES3FormatSet es3FormatSet = buildES3FormatSet();
return es3FormatSet;
}
// Map of sizes of input types
struct TypeInfo
{
GLuint mTypeBytes;
bool mSpecialInterpretation;
TypeInfo()
: mTypeBytes(0), mSpecialInterpretation(false) { }
TypeInfo(GLuint typeBytes, bool specialInterpretation)
: mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { }
bool operator<(const TypeInfo& other) const
{
return memcmp(this, &other, sizeof(TypeInfo)) < 0;
}
};
typedef std::pair<GLenum, TypeInfo> TypeInfoPair;
typedef std::map<GLenum, TypeInfo> TypeInfoMap;
static TypeInfoMap buildTypeInfoMap()
{
TypeInfoMap map;
map.insert(TypeInfoPair(GL_UNSIGNED_BYTE, TypeInfo( 1, false)));
map.insert(TypeInfoPair(GL_BYTE, TypeInfo( 1, false)));
map.insert(TypeInfoPair(GL_UNSIGNED_SHORT, TypeInfo( 2, false)));
map.insert(TypeInfoPair(GL_SHORT, TypeInfo( 2, false)));
map.insert(TypeInfoPair(GL_UNSIGNED_INT, TypeInfo( 4, false)));
map.insert(TypeInfoPair(GL_INT, TypeInfo( 4, false)));
map.insert(TypeInfoPair(GL_HALF_FLOAT, TypeInfo( 2, false)));
map.insert(TypeInfoPair(GL_FLOAT, TypeInfo( 4, false)));
map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5, TypeInfo( 2, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4, TypeInfo( 2, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1, TypeInfo( 2, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV, TypeInfo( 4, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8, TypeInfo( 4, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV, TypeInfo( 4, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV, TypeInfo( 4, true )));
map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 4, true )));
map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES, TypeInfo( 4, true )));
return map;
}
static bool getTypeInfo(GLenum type, TypeInfo *outTypeInfo)
{
static const TypeInfoMap infoMap = buildTypeInfoMap();
TypeInfoMap::const_iterator iter = infoMap.find(type);
if (iter != infoMap.end())
{
if (outTypeInfo)
{
*outTypeInfo = iter->second;
}
return true;
}
else
{
return false;
}
}
// Information about internal formats
typedef bool ((Context::*ContextSupportCheckMemberFunction)(void) const);
typedef bool (*ContextSupportCheckFunction)(const Context *context);
typedef bool ((rx::Renderer::*RendererSupportCheckMemberFunction)(void) const);
typedef bool (*ContextRendererSupportCheckFunction)(const Context *context, const rx::Renderer *renderer);
template <ContextSupportCheckMemberFunction func>
bool CheckSupport(const Context *context)
{
return (context->*func)();
}
template <ContextSupportCheckMemberFunction contextFunc, RendererSupportCheckMemberFunction rendererFunc>
bool CheckSupport(const Context *context, const rx::Renderer *renderer)
{
if (context)
{
return (context->*contextFunc)();
}
else if (renderer)
{
return (renderer->*rendererFunc)();
}
else
{
UNREACHABLE();
return false;
}
}
template <typename objectType>
bool AlwaysSupported(const objectType*)
{
return true;
}
template <typename objectTypeA, typename objectTypeB>
bool AlwaysSupported(const objectTypeA*, const objectTypeB*)
{
return true;
}
template <typename objectType>
bool NeverSupported(const objectType*)
{
return false;
}
template <typename objectTypeA, typename objectTypeB>
bool NeverSupported(const objectTypeA *, const objectTypeB *)
{
return false;
}
template <typename objectType>
bool UnimplementedSupport(const objectType*)
{
UNIMPLEMENTED();
return false;
}
template <typename objectTypeA, typename objectTypeB>
bool UnimplementedSupport(const objectTypeA*, const objectTypeB*)
{
UNIMPLEMENTED();
return false;
}
struct InternalFormatInfo
{
GLuint mRedBits;
GLuint mGreenBits;
GLuint mBlueBits;
GLuint mLuminanceBits;
GLuint mAlphaBits;
GLuint mSharedBits;
GLuint mDepthBits;
GLuint mStencilBits;
GLuint mPixelBits;
GLuint mComponentCount;
bool mIsCompressed;
GLuint mCompressedBlockWidth;
GLuint mCompressedBlockHeight;
GLenum mFormat;
GLenum mType;
ContextRendererSupportCheckFunction mIsColorRenderable;
ContextRendererSupportCheckFunction mIsDepthRenderable;
ContextRendererSupportCheckFunction mIsStencilRenderable;
ContextRendererSupportCheckFunction mIsTextureFilterable;
ContextSupportCheckFunction mSupportFunction;
InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0),
mPixelBits(0), mComponentCount(0), mIsCompressed(false), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
mIsColorRenderable(NeverSupported), mIsDepthRenderable(NeverSupported), mIsStencilRenderable(NeverSupported),
mIsTextureFilterable(NeverSupported), mSupportFunction(NeverSupported)
{
}
static InternalFormatInfo UnsizedFormat(GLenum format, ContextSupportCheckFunction supportFunction)
{
InternalFormatInfo formatInfo;
formatInfo.mFormat = format;
formatInfo.mSupportFunction = supportFunction;
return formatInfo;
}
static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
GLenum format, GLenum type, ContextRendererSupportCheckFunction colorRenderable,
ContextRendererSupportCheckFunction textureFilterable,
ContextSupportCheckFunction supportFunction)
{
InternalFormatInfo formatInfo;
formatInfo.mRedBits = red;
formatInfo.mGreenBits = green;
formatInfo.mBlueBits = blue;
formatInfo.mAlphaBits = alpha;
formatInfo.mSharedBits = shared;
formatInfo.mPixelBits = red + green + blue + alpha + shared;
formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
formatInfo.mFormat = format;
formatInfo.mType = type;
formatInfo.mIsColorRenderable = colorRenderable;
formatInfo.mIsTextureFilterable = textureFilterable;
formatInfo.mSupportFunction = supportFunction;
return formatInfo;
}
static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type,
ContextSupportCheckFunction supportFunction)
{
InternalFormatInfo formatInfo;
formatInfo.mLuminanceBits = luminance;
formatInfo.mAlphaBits = alpha;
formatInfo.mPixelBits = luminance + alpha;
formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
formatInfo.mFormat = format;
formatInfo.mType = type;
formatInfo.mIsTextureFilterable = AlwaysSupported;
formatInfo.mSupportFunction = supportFunction;
return formatInfo;
}
static InternalFormatInfo DepthStencilFormat(GLuint depth, GLuint stencil, GLenum format, GLenum type,
ContextRendererSupportCheckFunction depthRenderable,
ContextRendererSupportCheckFunction stencilRenderable,
ContextSupportCheckFunction supportFunction)
{
InternalFormatInfo formatInfo;
formatInfo.mDepthBits = depth;
formatInfo.mStencilBits = stencil;
formatInfo.mPixelBits = depth + stencil;
formatInfo.mComponentCount = ((depth > 0) ? 1 : 0) + ((stencil > 0) ? 1 : 0);
formatInfo.mFormat = format;
formatInfo.mType = type;
formatInfo.mIsDepthRenderable = depthRenderable;
formatInfo.mIsStencilRenderable = stencilRenderable;
formatInfo.mSupportFunction = supportFunction;
return formatInfo;
}
static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight,
GLuint compressedBlockSize, GLuint componentCount, GLenum format, GLenum type,
ContextSupportCheckFunction supportFunction)
{
InternalFormatInfo formatInfo;
formatInfo.mIsCompressed = true;
formatInfo.mCompressedBlockWidth = compressedBlockWidth;
formatInfo.mCompressedBlockHeight = compressedBlockHeight;
formatInfo.mPixelBits = compressedBlockSize;
formatInfo.mComponentCount = componentCount;
formatInfo.mFormat = format;
formatInfo.mType = type;
formatInfo.mIsTextureFilterable = AlwaysSupported;
formatInfo.mSupportFunction = supportFunction;
return formatInfo;
}
};
typedef std::pair<GLuint, InternalFormatInfo> InternalFormatInfoPair;
typedef std::map<GLuint, InternalFormatInfo> InternalFormatInfoMap;
static InternalFormatInfoMap buildES3InternalFormatInfoMap()
{
InternalFormatInfoMap map;
// From ES 3.0.1 spec, table 3.12
map.insert(InternalFormatInfoPair(GL_NONE, InternalFormatInfo()));
// | Internal format | | R | G | B | A |S | Format | Type | Color | Texture | Supported |
// | | | | | | | | | | renderable | filterable | |
map.insert(InternalFormatInfoPair(GL_R8, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_R8_SNORM, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, NeverSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG8, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, NeverSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, NeverSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB565, InternalFormatInfo::RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, NeverSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_RGBA4, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NeverSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_RGB5_A1, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, AlwaysSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_RGBA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, NeverSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB10_A2, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, AlwaysSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_SRGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, NeverSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, InternalFormatInfo::RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, NeverSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB9_E5, InternalFormatInfo::RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, NeverSupported, AlwaysSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_R8I, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_R8UI, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_R16I, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_R16UI, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_R32I, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_R32UI, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG8I, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG8UI, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG16I, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG16UI, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG32I, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG32UI, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, NeverSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NeverSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, NeverSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, NeverSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, NeverSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, NeverSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGBA8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGBA8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGBA16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGBA16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGBA32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGBA32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, AlwaysSupported, NeverSupported, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, AlwaysSupported, AlwaysSupported, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, AlwaysSupported, AlwaysSupported, AlwaysSupported )));
// Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
// | Internal format | | D |S | Format | Type | Color | Texture | Supported |
// | | | | | | | renderable | filterable | |
map.insert(InternalFormatInfoPair(GL_R16F, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG16F, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_RGBA16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_R32F, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RG32F, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_RGB32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_RGBA32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported )));
// Depth stencil formats
// | Internal format | | D |S | Format | Type | Color | Texture | Supported |
// | | | | | | | renderable | filterable | |
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, InternalFormatInfo::DepthStencilFormat(16, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, AlwaysSupported, NeverSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, InternalFormatInfo::DepthStencilFormat(24, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, AlwaysSupported, NeverSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,InternalFormatInfo::DepthStencilFormat(32, 0, GL_DEPTH_COMPONENT, GL_FLOAT, AlwaysSupported, NeverSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, InternalFormatInfo::DepthStencilFormat(24, 8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, InternalFormatInfo::DepthStencilFormat(32, 8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
// Luminance alpha formats
// | Internal format | | L | A | Format | Type | Supported |
// | | | | | | | |
map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, InternalFormatInfo::LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, InternalFormatInfo::LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, InternalFormatInfo::LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, AlwaysSupported)));
// Unsized formats
// | Internal format | | Format | Supported |
// | | | | |
map.insert(InternalFormatInfoPair(GL_ALPHA, InternalFormatInfo::UnsizedFormat(GL_ALPHA, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGB, InternalFormatInfo::UnsizedFormat(GL_RGB, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGBA, InternalFormatInfo::UnsizedFormat(GL_RGBA, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, AlwaysSupported)));
// Compressed formats, From ES 3.0.1 spec, table 3.16
// | Internal format | |W |H | B |C | Format | Type | Supported |
// | | | | | S |C | | | |
map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedSupport)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedSupport)));
// From GL_EXT_texture_compression_dxt1
// | Internal format | |W |H | B |C | Format | Type | Supported |
// | | | | | S |C | | | |
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, AlwaysSupported)));
// From GL_ANGLE_texture_compression_dxt3
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, AlwaysSupported)));
// From GL_ANGLE_texture_compression_dxt5
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, AlwaysSupported)));
return map;
}
static InternalFormatInfoMap buildES2InternalFormatInfoMap()
{
InternalFormatInfoMap map;
// From ES 2.0.25 table 4.5
map.insert(InternalFormatInfoPair(GL_NONE, InternalFormatInfo()));
// | Internal format | | R | G | B | A |S | Format | Type | Color | Texture | Supported |
// | | | | | | | | | | renderable | filterable | |
map.insert(InternalFormatInfoPair(GL_RGBA4, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGB5_A1, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGB565, InternalFormatInfo::RGBAFormat( 5, 6, 5, 0, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_6_5, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
// Extension formats
map.insert(InternalFormatInfoPair(GL_RGB8_OES, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGBA8_OES, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4, NeverSupported, AlwaysSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_5_5_1, NeverSupported, AlwaysSupported, AlwaysSupported)));
// Floating point formats have to query the renderer for support
// | Internal format | | R | G | B | A |S | Format | Type | Color | Texture | Supported |
// | | | | | | | | | | renderable | filterable | |
map.insert(InternalFormatInfoPair(GL_RGB16F_EXT, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT_OES, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
map.insert(InternalFormatInfoPair(GL_RGB32F_EXT, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
map.insert(InternalFormatInfoPair(GL_RGBA16F_EXT, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT_OES, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
map.insert(InternalFormatInfoPair(GL_RGBA32F_EXT, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
// Depth and stencil formats
// | Internal format | | D |S | Format | Type | Color | Texture | Supported |
// | | | | | | | renderable | filterable | |
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES,InternalFormatInfo::DepthStencilFormat(32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, AlwaysSupported, NeverSupported, CheckSupport<&Context::supportsDepthTextures>)));
map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8_OES, InternalFormatInfo::DepthStencilFormat(24, 8, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES, AlwaysSupported, AlwaysSupported, CheckSupport<&Context::supportsDepthTextures>)));
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, InternalFormatInfo::DepthStencilFormat(16, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, AlwaysSupported, NeverSupported, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, InternalFormatInfo::DepthStencilFormat( 0, 8, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_BYTE, NeverSupported, AlwaysSupported, AlwaysSupported)));
// Unsized formats
// | Internal format | | Format | Supported |
// | | | | |
map.insert(InternalFormatInfoPair(GL_ALPHA, InternalFormatInfo::UnsizedFormat(GL_ALPHA, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGB, InternalFormatInfo::UnsizedFormat(GL_RGB, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_RGBA, InternalFormatInfo::UnsizedFormat(GL_RGBA, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL_OES, InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL_OES, AlwaysSupported)));
// Luminance alpha formats from GL_EXT_texture_storage
// | Internal format | | L | A | Format | Type | Supported |
// | | | | | | | |
map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, InternalFormatInfo::LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, InternalFormatInfo::LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, InternalFormatInfo::LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, AlwaysSupported)));
map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, AlwaysSupported)));
// From GL_EXT_texture_compression_dxt1
// | Internal format | |W |H | B |C |Format | Type | Supported |
// | | | | | S |C | | | |
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, CheckSupport<&Context::supportsDXT1Textures>)));
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, CheckSupport<&Context::supportsDXT1Textures>)));
// From GL_ANGLE_texture_compression_dxt3
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, CheckSupport<&Context::supportsDXT3Textures>)));
// From GL_ANGLE_texture_compression_dxt5
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, CheckSupport<&Context::supportsDXT5Textures>)));
return map;
}
static bool getInternalFormatInfo(GLint internalFormat, GLuint clientVersion, InternalFormatInfo *outFormatInfo)
{
const InternalFormatInfoMap* map = NULL;
if (clientVersion == 2)
{
static const InternalFormatInfoMap formatMap = buildES2InternalFormatInfoMap();
map = &formatMap;
}
else if (clientVersion == 3)
{
static const InternalFormatInfoMap formatMap = buildES3InternalFormatInfoMap();
map = &formatMap;
}
else
{
UNREACHABLE();
}
InternalFormatInfoMap::const_iterator iter = map->find(internalFormat);
if (iter != map->end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
}
else
{
return false;
}
}
typedef std::set<GLenum> FormatSet;
static FormatSet buildES2ValidFormatSet()
{
static const FormatMap &formatMap = getES2FormatMap();
FormatSet set;
for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
{
const FormatTypePair& formatPair = i->first;
set.insert(formatPair.first);
}
return set;
}
static FormatSet buildES3ValidFormatSet()
{
static const ES3FormatSet &formatSet = getES3FormatSet();
FormatSet set;
for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
{
const FormatInfo& formatInfo = *i;
set.insert(formatInfo.mFormat);
}
return set;
}
typedef std::set<GLenum> TypeSet;
static TypeSet buildES2ValidTypeSet()
{
static const FormatMap &formatMap = getES2FormatMap();
TypeSet set;
for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
{
const FormatTypePair& formatPair = i->first;
set.insert(formatPair.second);
}
return set;
}
static TypeSet buildES3ValidTypeSet()
{
static const ES3FormatSet &formatSet = getES3FormatSet();
TypeSet set;
for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
{
const FormatInfo& formatInfo = *i;
set.insert(formatInfo.mType);
}
return set;
}
struct CopyConversion
{
GLenum mTextureFormat;
GLenum mFramebufferFormat;
CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
: mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
bool operator<(const CopyConversion& other) const
{
return memcmp(this, &other, sizeof(CopyConversion)) < 0;
}
};
typedef std::set<CopyConversion> CopyConversionSet;
static CopyConversionSet buildValidES3CopyTexImageCombinations()
{
CopyConversionSet set;
// From ES 3.0.1 spec, table 3.15
set.insert(CopyConversion(GL_ALPHA, GL_RGBA));
set.insert(CopyConversion(GL_LUMINANCE, GL_RED));
set.insert(CopyConversion(GL_LUMINANCE, GL_RG));
set.insert(CopyConversion(GL_LUMINANCE, GL_RGB));
set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA));
set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
set.insert(CopyConversion(GL_RED, GL_RED));
set.insert(CopyConversion(GL_RED, GL_RG));
set.insert(CopyConversion(GL_RED, GL_RGB));
set.insert(CopyConversion(GL_RED, GL_RGBA));
set.insert(CopyConversion(GL_RG, GL_RG));
set.insert(CopyConversion(GL_RG, GL_RGB));
set.insert(CopyConversion(GL_RG, GL_RGBA));
set.insert(CopyConversion(GL_RGB, GL_RGB));
set.insert(CopyConversion(GL_RGB, GL_RGBA));
set.insert(CopyConversion(GL_RGBA, GL_RGBA));
return set;
}
bool IsValidInternalFormat(GLint internalFormat, const Context *context)
{
if (!context)
{
return false;
}
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
{
ASSERT(internalFormatInfo.mSupportFunction != NULL);
return internalFormatInfo.mSupportFunction(context);
}
else
{
return false;
}
}
bool IsValidFormat(GLenum format, GLuint clientVersion)
{
if (clientVersion == 2)
{
static const FormatSet formatSet = buildES2ValidFormatSet();
return formatSet.find(format) != formatSet.end();
}
else if (clientVersion == 3)
{
static const FormatSet formatSet = buildES3ValidFormatSet();
return formatSet.find(format) != formatSet.end();
}
else
{
UNREACHABLE();
return false;
}
}
bool IsValidType(GLenum type, GLuint clientVersion)
{
if (clientVersion == 2)
{
static const TypeSet typeSet = buildES2ValidTypeSet();
return typeSet.find(type) != typeSet.end();
}
else if (clientVersion == 3)
{
static const TypeSet typeSet = buildES3ValidTypeSet();
return typeSet.find(type) != typeSet.end();
}
else
{
UNREACHABLE();
return false;
}
}
bool IsValidFormatCombination(GLint internalFormat, GLenum format, GLenum type, GLuint clientVersion)
{
if (clientVersion == 2)
{
static const FormatMap &formats = getES2FormatMap();
FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second));
}
else if (clientVersion == 3)
{
static const ES3FormatSet &formats = getES3FormatSet();
return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
}
else
{
UNREACHABLE();
return false;
}
}
bool IsValidCopyTexImageCombination(GLenum textureFormat, GLenum frameBufferFormat, GLuint clientVersion)
{
if (clientVersion == 2)
{
UNIMPLEMENTED();
return false;
}
else if (clientVersion == 3)
{
static const CopyConversionSet conversionSet = buildValidES3CopyTexImageCombinations();
return conversionSet.find(CopyConversion(textureFormat, frameBufferFormat)) != conversionSet.end();
}
else
{
UNREACHABLE();
return false;
}
}
bool IsSizedInternalFormat(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mPixelBits > 0;
}
else
{
UNREACHABLE();
return false;
}
}
GLint GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion)
{
if (clientVersion == 2)
{
static const FormatMap &formats = getES2FormatMap();
FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
return (iter != formats.end()) ? iter->second : GL_NONE;
}
else if (clientVersion == 3)
{
static const FormatMap formats = buildES3FormatMap();
FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
return (iter != formats.end()) ? iter->second : GL_NONE;
}
else
{
UNREACHABLE();
return GL_NONE;
}
}
GLuint GetPixelBytes(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mPixelBits / 8;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetAlphaBits(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mAlphaBits;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetRedBits(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mRedBits;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetGreenBits(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mGreenBits;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlueBits(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mGreenBits;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetLuminanceBits(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mLuminanceBits;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetDepthBits(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mDepthBits;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetStencilBits(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mStencilBits;
}
else
{
UNREACHABLE();
return 0;
}
}
GLenum GetFormat(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mFormat;
}
else
{
UNREACHABLE();
return GL_NONE;
}
}
GLenum GetType(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mType;
}
else
{
UNREACHABLE();
return GL_NONE;
}
}
bool IsColorRenderingSupported(GLint internalFormat, const rx::Renderer *renderer)
{
InternalFormatInfo internalFormatInfo;
if (renderer && getInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsColorRenderable(NULL, renderer);
}
else
{
UNREACHABLE();
return false;
}
}
bool IsColorRenderingSupported(GLint internalFormat, const Context *context)
{
InternalFormatInfo internalFormatInfo;
if (context && getInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsColorRenderable(context, NULL);
}
else
{
UNREACHABLE();
return false;
}
}
bool IsTextureFilteringSupported(GLint internalFormat, const rx::Renderer *renderer)
{
InternalFormatInfo internalFormatInfo;
if (renderer && getInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsTextureFilterable(NULL, renderer);
}
else
{
UNREACHABLE();
return false;
}
}
bool IsTextureFilteringSupported(GLint internalFormat, const Context *context)
{
InternalFormatInfo internalFormatInfo;
if (context && getInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsTextureFilterable(context, NULL);
}
else
{
UNREACHABLE();
return false;
}
}
bool IsDepthRenderingSupported(GLint internalFormat, const rx::Renderer *renderer)
{
InternalFormatInfo internalFormatInfo;
if (renderer && getInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsDepthRenderable(NULL, renderer);
}
else
{
UNREACHABLE();
return false;
}
}
bool IsDepthRenderingSupported(GLint internalFormat, const Context *context)
{
InternalFormatInfo internalFormatInfo;
if (context && getInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsDepthRenderable(context, NULL);
}
else
{
UNREACHABLE();
return false;
}
}
bool IsStencilRenderingSupported(GLint internalFormat, const rx::Renderer *renderer)
{
InternalFormatInfo internalFormatInfo;
if (renderer && getInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsStencilRenderable(NULL, renderer);
}
else
{
UNREACHABLE();
return false;
}
}
bool IsStencilRenderingSupported(GLint internalFormat, const Context *context)
{
InternalFormatInfo internalFormatInfo;
if (context && getInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
{
return internalFormatInfo.mIsStencilRenderable(context, NULL);
}
else
{
UNREACHABLE();
return false;
}
}
GLuint GetRowPitch(GLint internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment)
{
ASSERT(alignment > 0 && isPow2(alignment));
return (GetBlockSize(internalFormat, type, clientVersion, width, 1) + alignment - 1) & ~(alignment - 1);
}
GLuint GetDepthPitch(GLint internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment)
{
return (GetBlockSize(internalFormat, type, clientVersion, width, height) + alignment - 1) & ~(alignment - 1);
}
GLuint GetBlockSize(GLint internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
if (internalFormatInfo.mIsCompressed)
{
GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
}
else
{
TypeInfo typeInfo;
if (getTypeInfo(type, &typeInfo))
{
if (typeInfo.mSpecialInterpretation)
{
return typeInfo.mTypeBytes * width * height;
}
else
{
return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
}
}
else
{
UNREACHABLE();
return 0;
}
}
}
else
{
UNREACHABLE();
return 0;
}
}
bool IsFormatCompressed(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mIsCompressed;
}
else
{
UNREACHABLE();
return false;
}
}
GLuint GetCompressedBlockWidth(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mCompressedBlockWidth;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetCompressedBlockHeight(GLint internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (getInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
{
return internalFormatInfo.mCompressedBlockHeight;
}
else
{
UNREACHABLE();
return 0;
}
}
}
//
// Copyright (c) 2013 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.
//
// formatutils.h: Queries for GL image formats.
#ifndef LIBGLESV2_FORMATUTILS_H_
#define LIBGLESV2_FORMATUTILS_H_
#define GL_APICALL
#include <GLES3/gl3.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
unsigned char *destData, int destRowPitch, int destDepthPitch);
typedef void (*LoadImageFunction)(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
namespace rx
{
class Renderer;
}
namespace gl
{
class Context;
bool IsValidInternalFormat(GLint internalFormat, const Context *context);
bool IsValidFormat(GLenum format, GLuint clientVersion);
bool IsValidType(GLenum type, GLuint clientVersion);
bool IsValidFormatCombination(GLint internalFormat, GLenum format, GLenum type, GLuint clientVersion);
bool IsValidCopyTexImageCombination(GLenum textureFormat, GLenum frameBufferFormat, GLuint clientVersion);
bool IsSizedInternalFormat(GLint internalFormat, GLuint clientVersion);
GLint GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion);
GLuint GetPixelBytes(GLint internalFormat, GLuint clientVersion);
GLuint GetAlphaBits(GLint internalFormat, GLuint clientVersion);
GLuint GetRedBits(GLint internalFormat, GLuint clientVersion);
GLuint GetGreenBits(GLint internalFormat, GLuint clientVersion);
GLuint GetBlueBits(GLint internalFormat, GLuint clientVersion);
GLuint GetLuminanceBits(GLint internalFormat, GLuint clientVersion);
GLuint GetDepthBits(GLint internalFormat, GLuint clientVersion);
GLuint GetStencilBits(GLint internalFormat, GLuint clientVersion);
GLenum GetFormat(GLint internalFormat, GLuint clientVersion);
GLenum GetType(GLint internalFormat, GLuint clientVersion);
bool IsColorRenderingSupported(GLint internalFormat, const rx::Renderer *renderer);
bool IsColorRenderingSupported(GLint internalFormat, const Context *context);
bool IsTextureFilteringSupported(GLint internalFormat, const rx::Renderer *renderer);
bool IsTextureFilteringSupported(GLint internalFormat, const Context *context);
bool IsDepthRenderingSupported(GLint internalFormat, const rx::Renderer *renderer);
bool IsDepthRenderingSupported(GLint internalFormat, const Context *context);
bool IsStencilRenderingSupported(GLint internalFormat, const rx::Renderer *renderer);
bool IsStencilRenderingSupported(GLint internalFormat, const Context *context);
GLuint GetRowPitch(GLint internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment);
GLuint GetDepthPitch(GLint internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment);
GLuint GetBlockSize(GLint internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height);
bool IsFormatCompressed(GLint internalFormat, GLuint clientVersion);
GLuint GetCompressedBlockWidth(GLint internalFormat, GLuint clientVersion);
GLuint GetCompressedBlockHeight(GLint internalFormat, GLuint clientVersion);
}
#endif LIBGLESV2_FORMATUTILS_H_
...@@ -244,6 +244,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -244,6 +244,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
</ClCompile> </ClCompile>
<ClCompile Include="Fence.cpp" /> <ClCompile Include="Fence.cpp" />
<ClCompile Include="Float16ToFloat32.cpp" /> <ClCompile Include="Float16ToFloat32.cpp" />
<ClCompile Include="formatutils.cpp" />
<ClCompile Include="Framebuffer.cpp" /> <ClCompile Include="Framebuffer.cpp" />
<ClCompile Include="HandleAllocator.cpp" /> <ClCompile Include="HandleAllocator.cpp" />
<ClCompile Include="libGLESv2.cpp" /> <ClCompile Include="libGLESv2.cpp" />
...@@ -265,6 +266,8 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -265,6 +266,8 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClCompile Include="renderer\BufferStorage.cpp" /> <ClCompile Include="renderer\BufferStorage.cpp" />
<ClCompile Include="renderer\BufferStorage11.cpp" /> <ClCompile Include="renderer\BufferStorage11.cpp" />
<ClCompile Include="renderer\BufferStorage9.cpp" /> <ClCompile Include="renderer\BufferStorage9.cpp" />
<ClCompile Include="renderer\formatutils11.cpp" />
<ClCompile Include="renderer\formatutils9.cpp" />
<ClCompile Include="renderer\Image.cpp" /> <ClCompile Include="renderer\Image.cpp" />
<ClCompile Include="renderer\Image9.cpp" /> <ClCompile Include="renderer\Image9.cpp" />
<ClCompile Include="renderer\IndexBuffer.cpp" /> <ClCompile Include="renderer\IndexBuffer.cpp" />
...@@ -274,6 +277,8 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -274,6 +277,8 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClCompile Include="renderer\ImageSSE2.cpp" /> <ClCompile Include="renderer\ImageSSE2.cpp" />
<ClCompile Include="renderer\Image11.cpp" /> <ClCompile Include="renderer\Image11.cpp" />
<ClCompile Include="renderer\InputLayoutCache.cpp" /> <ClCompile Include="renderer\InputLayoutCache.cpp" />
<ClCompile Include="renderer\loadimage.cpp" />
<ClCompile Include="renderer\loadimageSSE2.cpp" />
<ClCompile Include="renderer\Query11.cpp" /> <ClCompile Include="renderer\Query11.cpp" />
<ClCompile Include="renderer\Query9.cpp" /> <ClCompile Include="renderer\Query9.cpp" />
<ClCompile Include="renderer\Renderer.cpp" /> <ClCompile Include="renderer\Renderer.cpp" />
...@@ -318,6 +323,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -318,6 +323,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClInclude Include="constants.h" /> <ClInclude Include="constants.h" />
<ClInclude Include="Context.h" /> <ClInclude Include="Context.h" />
<ClInclude Include="Fence.h" /> <ClInclude Include="Fence.h" />
<ClInclude Include="formatutils.h" />
<ClInclude Include="Framebuffer.h" /> <ClInclude Include="Framebuffer.h" />
<ClInclude Include="HandleAllocator.h" /> <ClInclude Include="HandleAllocator.h" />
<ClInclude Include="main.h" /> <ClInclude Include="main.h" />
...@@ -335,6 +341,8 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -335,6 +341,8 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClInclude Include="renderer\BufferStorage.h" /> <ClInclude Include="renderer\BufferStorage.h" />
<ClInclude Include="renderer\BufferStorage11.h" /> <ClInclude Include="renderer\BufferStorage11.h" />
<ClInclude Include="renderer\BufferStorage9.h" /> <ClInclude Include="renderer\BufferStorage9.h" />
<ClInclude Include="renderer\formatutils11.h" />
<ClInclude Include="renderer\formatutils9.h" />
<ClInclude Include="renderer\generatemip.h" /> <ClInclude Include="renderer\generatemip.h" />
<ClInclude Include="renderer\Image.h" /> <ClInclude Include="renderer\Image.h" />
<ClInclude Include="renderer\Image11.h" /> <ClInclude Include="renderer\Image11.h" />
...@@ -344,6 +352,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -344,6 +352,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClInclude Include="renderer\IndexBuffer9.h" /> <ClInclude Include="renderer\IndexBuffer9.h" />
<ClInclude Include="renderer\IndexDataManager.h" /> <ClInclude Include="renderer\IndexDataManager.h" />
<ClInclude Include="renderer\InputLayoutCache.h" /> <ClInclude Include="renderer\InputLayoutCache.h" />
<ClInclude Include="renderer\loadimage.h" />
<ClInclude Include="renderer\Query11.h" /> <ClInclude Include="renderer\Query11.h" />
<ClInclude Include="renderer\QueryImpl.h" /> <ClInclude Include="renderer\QueryImpl.h" />
<ClInclude Include="renderer\Query9.h" /> <ClInclude Include="renderer\Query9.h" />
......
...@@ -218,6 +218,21 @@ ...@@ -218,6 +218,21 @@
<ClCompile Include="precompiled.cpp"> <ClCompile Include="precompiled.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="renderer\loadimage.cpp">
<Filter>Source Files\Renderer</Filter>
</ClCompile>
<ClCompile Include="renderer\loadimageSSE2.cpp">
<Filter>Source Files\Renderer</Filter>
</ClCompile>
<ClCompile Include="renderer\formatutils9.cpp">
<Filter>Source Files\Renderer9</Filter>
</ClCompile>
<ClCompile Include="renderer\formatutils11.cpp">
<Filter>Source Files\Renderer11</Filter>
</ClCompile>
<ClCompile Include="formatutils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="BinaryStream.h"> <ClInclude Include="BinaryStream.h">
...@@ -493,6 +508,18 @@ ...@@ -493,6 +508,18 @@
<ClInclude Include="renderer\shaders\compiled\clearsingle11ps.h"> <ClInclude Include="renderer\shaders\compiled\clearsingle11ps.h">
<Filter>Shaders\Compiled</Filter> <Filter>Shaders\Compiled</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="renderer\loadimage.h">
<Filter>Header Files\Renderer</Filter>
</ClInclude>
<ClInclude Include="renderer\formatutils11.h">
<Filter>Header Files\Renderer11</Filter>
</ClInclude>
<ClInclude Include="renderer\formatutils9.h">
<Filter>Header Files\Renderer9</Filter>
</ClInclude>
<ClInclude Include="formatutils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="renderer\shaders\Blit.ps"> <None Include="renderer\shaders\Blit.ps">
......
#include "precompiled.h"
//
// Copyright (c) 2013 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.
//
// formatutils11.cpp: Queries for GL image formats and their translations to D3D11
// formats.
#include "libGLESv2/renderer/formatutils11.h"
#include "libGLESv2/renderer/generatemip.h"
#include "libGLESv2/renderer/loadimage.h"
namespace rx
{
struct D3D11ES3FormatInfo
{
DXGI_FORMAT mTexFormat;
DXGI_FORMAT mSRVFormat;
DXGI_FORMAT mRTVFormat;
DXGI_FORMAT mDSVFormat;
D3D11ES3FormatInfo()
: mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN)
{ }
D3D11ES3FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
: mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat)
{ }
};
// For sized GL internal formats, there is only one corresponding D3D11 format. This map type allows
// querying for the DXGI texture formats to use for textures, SRVs, RTVs and DSVs given a GL internal
// format.
typedef std::pair<GLint, D3D11ES3FormatInfo> D3D11ES3FormatPair;
typedef std::map<GLint, D3D11ES3FormatInfo> D3D11ES3FormatMap;
static D3D11ES3FormatMap buildD3D11ES3FormatMap()
{
D3D11ES3FormatMap map;
// | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
map.insert(D3D11ES3FormatPair(GL_NONE, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R8, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG8, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB565, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA4, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB5_A1, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA8_SNORM, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB10_A2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB10_A2UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_SRGB8, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_SRGB8_ALPHA8, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R16F, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG16F, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB16F, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA16F, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R32F, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG32F, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R11F_G11F_B10F, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB9_E5, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R8I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R8UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R16I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R16UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R32I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_R32UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG8I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG8UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG16I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG16UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG32I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RG32UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB8I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB8UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB16I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB16UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB32I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB32UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA8I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA8UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA16I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA16UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA32I, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA32UI, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
// Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format?
map.insert(D3D11ES3FormatPair(GL_ALPHA, D3D11ES3FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGB, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_RGBA, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_BGRA_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN)));
// From GL_EXT_texture_storage
// | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
map.insert(D3D11ES3FormatPair(GL_ALPHA8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_ALPHA32F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE32F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_ALPHA16F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE16F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_BGRA8_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_BGRA4_ANGLEX, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN )));
map.insert(D3D11ES3FormatPair(GL_BGR5_A1_ANGLEX, D3D11ES3FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN )));
// Depth stencil formats
map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT16, D3D11ES3FormatInfo(DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM )));
map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT24, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT )));
map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32F, D3D11ES3FormatInfo(DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT )));
map.insert(D3D11ES3FormatPair(GL_DEPTH24_STENCIL8, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT )));
map.insert(D3D11ES3FormatPair(GL_DEPTH32F_STENCIL8, D3D11ES3FormatInfo(DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT )));
// From GL_ANGLE_depth_texture
map.insert(D3D11ES3FormatPair(GL_DEPTH_COMPONENT32_OES, D3D11ES3FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT )));
// Compressed formats, From ES 3.0.1 spec, table 3.16
// | GL internal format | | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_R11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_R11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RG11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SIGNED_RG11_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA8_ETC2_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, D3D11ES3FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
// From GL_EXT_texture_compression_dxt1
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D11ES3FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
// From GL_ANGLE_texture_compression_dxt3
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D11ES3FormatInfo(DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
// From GL_ANGLE_texture_compression_dxt5
map.insert(D3D11ES3FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D11ES3FormatInfo(DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN)));
return map;
}
static bool getD3D11ES3FormatInfo(GLint internalFormat, GLuint clientVersion, D3D11ES3FormatInfo *outFormatInfo)
{
static const D3D11ES3FormatMap formatMap = buildD3D11ES3FormatMap();
D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat);
if (iter != formatMap.end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
}
else
{
return false;
}
}
// ES3 image loading functions vary based on the internal format and data type given,
// this map type determines the loading function from the internal format and type supplied
// to glTex*Image*D
typedef std::pair<GLint, GLenum> InternalFormatTypePair;
typedef std::pair<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionPair;
typedef std::map<InternalFormatTypePair, LoadImageFunction> D3D11LoadFunctionMap;
static void UnimplementedLoadFunction(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
UNIMPLEMENTED();
}
// A helper function to insert data into the D3D11LoadFunctionMap with fewer characters.
static inline void insertLoadFunction(D3D11LoadFunctionMap *map, GLint internalFormat, GLenum type,
LoadImageFunction loadFunc)
{
map->insert(D3D11LoadFunctionPair(InternalFormatTypePair(internalFormat, type), loadFunc));
}
D3D11LoadFunctionMap buildD3D11LoadFunctionMap()
{
D3D11LoadFunctionMap map;
// | Internal format | Type | Load function |
insertLoadFunction(&map, GL_RGBA8, GL_UNSIGNED_BYTE, loadRGBAUByteDataToNative );
insertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, loadRGBAUByteDataToNative );
insertLoadFunction(&map, GL_RGBA8_SNORM, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, loadRGBA4444DataToRGBA );
insertLoadFunction(&map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, loadRGBA5551DataToRGBA );
insertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT, loadRGBAHalfFloatDataToRGBA );
insertLoadFunction(&map, GL_RGBA32F, GL_FLOAT, loadRGBAFloatDataToRGBA );
insertLoadFunction(&map, GL_RGBA16F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA8UI, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA8I, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA16UI, GL_UNSIGNED_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA16I, GL_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA32UI, GL_UNSIGNED_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA32I, GL_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB8, GL_UNSIGNED_BYTE, loadRGBUByteDataToRGBA );
insertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_SRGB8, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB8_SNORM, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, loadRGB565DataToRGBA );
insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB16F, GL_HALF_FLOAT, loadRGBHalfFloatDataToRGBA );
insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB32F, GL_FLOAT, loadRGBFloatDataToNative );
insertLoadFunction(&map, GL_RGB16F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R11F_G11F_B10F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB9_E5, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB8UI, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB8I, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB16UI, GL_UNSIGNED_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB16I, GL_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB32UI, GL_UNSIGNED_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB32I, GL_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG8, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG8_SNORM, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG16F, GL_HALF_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG32F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG16F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG8UI, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG8I, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG16UI, GL_UNSIGNED_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG16I, GL_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG32UI, GL_UNSIGNED_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RG32I, GL_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R8, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R8_SNORM, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R16F, GL_HALF_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R32F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R16F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R8UI, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R8I, GL_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R16UI, GL_UNSIGNED_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R16I, GL_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R32UI, GL_UNSIGNED_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_R32I, GL_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_INT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, UnimplementedLoadFunction );
// Unsized formats
insertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_ALPHA, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
// From GL_OES_texture_float
insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, loadLuminanceAlphaFloatDataToRGBA );
insertLoadFunction(&map, GL_LUMINANCE, GL_FLOAT, loadLuminanceFloatDataToRGB );
insertLoadFunction(&map, GL_ALPHA, GL_FLOAT, loadAlphaFloatDataToRGBA );
// From GL_OES_texture_half_float
insertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, loadLuminanceAlphaHalfFloatDataToRGBA);
insertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT, loadLuminanceHalfFloatDataToRGBA );
insertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT, loadAlphaHalfFloatDataToRGBA );
// From GL_EXT_texture_storage
insertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, loadAlphaDataToNative );
insertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, loadLuminanceDataToBGRA );
insertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, loadLuminanceAlphaDataToBGRA );
insertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, loadAlphaFloatDataToRGBA );
insertLoadFunction(&map, GL_LUMINANCE32F_EXT, GL_FLOAT, loadLuminanceFloatDataToRGB );
insertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT, loadLuminanceAlphaFloatDataToRGBA );
insertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT, loadAlphaHalfFloatDataToRGBA );
insertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT, loadLuminanceHalfFloatDataToRGBA );
insertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT, loadLuminanceAlphaHalfFloatDataToRGBA);
insertLoadFunction(&map, GL_BGRA8_EXT, GL_UNSIGNED_BYTE, loadBGRADataToBGRA );
insertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, loadRGBA4444DataToRGBA );
insertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, loadRGBA5551DataToRGBA );
insertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
// Compressed formats
// From ES 3.0.1 spec, table 3.16
// | Internal format | Type | Load function |
insertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
insertLoadFunction(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction );
// From GL_EXT_texture_compression_dxt1
insertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 8>);
insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 8>);
// From GL_ANGLE_texture_compression_dxt3
insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 16>);
// From GL_ANGLE_texture_compression_dxt5
insertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, loadCompressedBlockDataToNative<4, 4, 16>);
return map;
}
struct D3D11ES2FormatInfo
{
DXGI_FORMAT mTexFormat;
DXGI_FORMAT mSRVFormat;
DXGI_FORMAT mRTVFormat;
DXGI_FORMAT mDSVFormat;
LoadImageFunction mLoadImageFunction;
D3D11ES2FormatInfo()
: mTexFormat(DXGI_FORMAT_UNKNOWN), mDSVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN),
mSRVFormat(DXGI_FORMAT_UNKNOWN), mLoadImageFunction(NULL)
{ }
D3D11ES2FormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat,
LoadImageFunction loadFunc)
: mTexFormat(texFormat), mDSVFormat(dsvFormat), mRTVFormat(rtvFormat), mSRVFormat(srvFormat),
mLoadImageFunction(loadFunc)
{ }
};
// ES2 internal formats can map to DXGI formats and loading functions
typedef std::pair<GLint, D3D11ES2FormatInfo> D3D11ES2FormatPair;
typedef std::map<GLint, D3D11ES2FormatInfo> D3D11ES2FormatMap;
static D3D11ES2FormatMap buildD3D11ES2FormatMap()
{
D3D11ES2FormatMap map;
// | Internal format | | Texture format | SRV format | RTV format | DSV format | Load function |
map.insert(D3D11ES2FormatPair(GL_NONE, D3D11ES2FormatInfo(DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, NULL )));
map.insert(D3D11ES2FormatPair(GL_DEPTH_COMPONENT16, D3D11ES2FormatInfo(DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM, NULL )));
map.insert(D3D11ES2FormatPair(GL_DEPTH_COMPONENT32_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT, NULL )));
map.insert(D3D11ES2FormatPair(GL_DEPTH24_STENCIL8_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT, NULL )));
map.insert(D3D11ES2FormatPair(GL_STENCIL_INDEX8, D3D11ES2FormatInfo(DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT, NULL )));
map.insert(D3D11ES2FormatPair(GL_RGBA32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBAFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_RGB32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBFloatDataToNative )));
map.insert(D3D11ES2FormatPair(GL_ALPHA32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadAlphaFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_LUMINANCE32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceFloatDataToRGB )));
map.insert(D3D11ES2FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceAlphaFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_RGBA16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBAHalfFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_RGB16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadRGBHalfFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_ALPHA16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadAlphaHalfFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_LUMINANCE16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceHalfFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, loadLuminanceAlphaHalfFloatDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_ALPHA8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN, loadAlphaDataToNative )));
map.insert(D3D11ES2FormatPair(GL_LUMINANCE8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadLuminanceDataToBGRA )));
map.insert(D3D11ES2FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadLuminanceAlphaDataToBGRA )));
map.insert(D3D11ES2FormatPair(GL_RGB8_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBUByteDataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_RGB565, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGB565DataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_RGBA8_OES, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBAUByteDataToNative )));
map.insert(D3D11ES2FormatPair(GL_RGBA4, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA4444DataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_RGB5_A1, D3D11ES2FormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA5551DataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_BGRA8_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadBGRADataToBGRA )));
map.insert(D3D11ES2FormatPair(GL_BGRA4_ANGLEX, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA4444DataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_BGR5_A1_ANGLEX, D3D11ES2FormatInfo(DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, loadRGBA5551DataToRGBA )));
map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 8>)));
map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D11ES2FormatInfo(DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 8>)));
map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D11ES2FormatInfo(DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 16>)));
map.insert(D3D11ES2FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D11ES2FormatInfo(DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, loadCompressedBlockDataToNative<4, 4, 16>)));
return map;
}
static bool getD3D11ES2FormatInfo(GLint internalFormat, GLuint clientVersion, D3D11ES2FormatInfo *outFormatInfo)
{
static const D3D11ES2FormatMap formatMap = buildD3D11ES2FormatMap();
D3D11ES2FormatMap::const_iterator iter = formatMap.find(internalFormat);
if (iter != formatMap.end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
}
else
{
return false;
}
}
// A map for determining the mip map generation function given a texture's internal DXGI format
typedef std::pair<DXGI_FORMAT, MipGenerationFunction> FormatMipPair;
typedef std::map<DXGI_FORMAT, MipGenerationFunction> FormatMipMap;
static FormatMipMap buildFormatMipMap()
{
FormatMipMap map;
// | DXGI format | Mip generation function |
map.insert(FormatMipPair(DXGI_FORMAT_A8_UNORM, GenerateMip<A8> ));
map.insert(FormatMipPair(DXGI_FORMAT_R8_UNORM, GenerateMip<R8> ));
map.insert(FormatMipPair(DXGI_FORMAT_R8G8_UNORM, GenerateMip<R8G8> ));
map.insert(FormatMipPair(DXGI_FORMAT_R8G8B8A8_UNORM, GenerateMip<R8G8B8A8> ));
map.insert(FormatMipPair(DXGI_FORMAT_B8G8R8A8_UNORM, GenerateMip<B8G8R8A8> ));
map.insert(FormatMipPair(DXGI_FORMAT_R16_FLOAT, GenerateMip<R16F> ));
map.insert(FormatMipPair(DXGI_FORMAT_R16G16_FLOAT, GenerateMip<R16G16F> ));
map.insert(FormatMipPair(DXGI_FORMAT_R16G16B16A16_FLOAT, GenerateMip<R16G16B16A16F>));
map.insert(FormatMipPair(DXGI_FORMAT_R32_FLOAT, GenerateMip<R32F> ));
map.insert(FormatMipPair(DXGI_FORMAT_R32G32_FLOAT, GenerateMip<R32G32F> ));
map.insert(FormatMipPair(DXGI_FORMAT_R32G32B32_FLOAT, GenerateMip<R32G32B32F> ));
map.insert(FormatMipPair(DXGI_FORMAT_R32G32B32A32_FLOAT, GenerateMip<R32G32B32A32F>));
return map;
}
// A map to determine the pixel size of a given DXGI format
struct DXGIFormatInfo
{
GLuint mPixelBits;
GLuint mBlockWidth;
GLuint mBlockHeight;
GLint mInternalFormat;
DXGIFormatInfo()
: mPixelBits(0), mInternalFormat(GL_NONE)
{ }
DXGIFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLint internalFormat)
: mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat)
{ }
};
typedef std::pair<DXGI_FORMAT, DXGIFormatInfo> DXGIFormatInfoPair;
typedef std::map<DXGI_FORMAT, DXGIFormatInfo> DXGIFormatInfoMap;
static DXGIFormatInfoMap buildDXGIFormatInfoMap()
{
DXGIFormatInfoMap map;
// | DXGI format | S |W |H | Internal format |
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_UNKNOWN, DXGIFormatInfo( 0, 0, 0, GL_NONE )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_A8_UNORM, DXGIFormatInfo( 8, 1, 1, GL_ALPHA8_EXT )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R8_UNORM, DXGIFormatInfo( 8, 1, 1, GL_R8 )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R8G8_UNORM, DXGIFormatInfo( 16, 1, 1, GL_RG8 )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R8G8B8A8_UNORM, DXGIFormatInfo( 32, 1, 1, GL_RGBA8 )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGIFormatInfo( 32, 1, 1, GL_SRGB8_ALPHA8 )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_B8G8R8A8_UNORM, DXGIFormatInfo( 32, 1, 1, GL_BGRA8_EXT )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R10G10B10A2_UNORM, DXGIFormatInfo( 32, 1, 1, GL_RGB10_A2 )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R16_FLOAT, DXGIFormatInfo( 16, 1, 1, GL_R16F )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R16G16_FLOAT, DXGIFormatInfo( 32, 1, 1, GL_RG16F )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGIFormatInfo( 64, 1, 1, GL_RGBA16F )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R32_FLOAT, DXGIFormatInfo( 32, 1, 1, GL_R32F )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R32G32_FLOAT, DXGIFormatInfo( 64, 1, 1, GL_RG32F )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R32G32B32_FLOAT, DXGIFormatInfo( 96, 1, 1, GL_RGB32F )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGIFormatInfo(128, 1, 1, GL_RGBA32F )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R16_TYPELESS, DXGIFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16 )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_D16_UNORM, DXGIFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16 )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R32_TYPELESS, DXGIFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_D32_FLOAT, DXGIFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_R24G8_TYPELESS, DXGIFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_D24_UNORM_S8_UINT, DXGIFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_BC1_UNORM, DXGIFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_BC2_UNORM, DXGIFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)));
map.insert(DXGIFormatInfoPair(DXGI_FORMAT_BC3_UNORM, DXGIFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)));
return map;
}
static bool getDXGIFormatInfo(DXGI_FORMAT format, DXGIFormatInfo *outFormatInfo)
{
static const DXGIFormatInfoMap infoMap = buildDXGIFormatInfoMap();
DXGIFormatInfoMap::const_iterator iter = infoMap.find(format);
if (iter != infoMap.end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
}
else
{
return false;
}
}
namespace d3d11
{
MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format)
{
static const FormatMipMap formatMipMap = buildFormatMipMap();
FormatMipMap::const_iterator iter = formatMipMap.find(format);
if (iter != formatMipMap.end())
{
return iter->second;
}
else
{
UNREACHABLE();
return NULL;
}
}
LoadImageFunction GetImageLoadFunction(GLint internalFormat, GLenum type, GLuint clientVersion)
{
if (clientVersion == 2)
{
D3D11ES2FormatInfo d3d11FormatInfo;
if (getD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mLoadImageFunction;
}
else
{
UNREACHABLE();
return NULL;
}
}
else if (clientVersion == 3)
{
static const D3D11LoadFunctionMap loadImageMap = buildD3D11LoadFunctionMap();
D3D11LoadFunctionMap::const_iterator iter = loadImageMap.find(InternalFormatTypePair(internalFormat, type));
if (iter != loadImageMap.end())
{
return iter->second;
}
else
{
UNREACHABLE();
return NULL;
}
}
else
{
UNREACHABLE();
return NULL;
}
}
GLuint GetFormatPixelBytes(DXGI_FORMAT format)
{
DXGIFormatInfo dxgiFormatInfo;
if (getDXGIFormatInfo(format, &dxgiFormatInfo))
{
return dxgiFormatInfo.mPixelBits / 8;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlockWidth(DXGI_FORMAT format)
{
DXGIFormatInfo dxgiFormatInfo;
if (getDXGIFormatInfo(format, &dxgiFormatInfo))
{
return dxgiFormatInfo.mBlockWidth;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlockHeight(DXGI_FORMAT format)
{
DXGIFormatInfo dxgiFormatInfo;
if (getDXGIFormatInfo(format, &dxgiFormatInfo))
{
return dxgiFormatInfo.mBlockHeight;
}
else
{
UNREACHABLE();
return 0;
}
}
void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
{
DXGIFormatInfo dxgiFormatInfo;
if (getDXGIFormatInfo(format, &dxgiFormatInfo))
{
int upsampleCount = 0;
GLsizei blockWidth = dxgiFormatInfo.mBlockWidth;
GLsizei blockHeight = dxgiFormatInfo.mBlockHeight;
// Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight)
{
while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0)
{
*requestWidth <<= 1;
*requestHeight <<= 1;
upsampleCount++;
}
}
*levelOffset = upsampleCount;
}
else
{
UNREACHABLE();
}
}
}
namespace gl_d3d11
{
DXGI_FORMAT GetTexFormat(GLint internalFormat, GLuint clientVersion)
{
if (clientVersion == 2)
{
D3D11ES2FormatInfo d3d11FormatInfo;
if (getD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mTexFormat;
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
else if (clientVersion == 3)
{
D3D11ES3FormatInfo d3d11FormatInfo;
if (getD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mTexFormat;
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
DXGI_FORMAT GetSRVFormat(GLint internalFormat, GLuint clientVersion)
{
if (clientVersion == 2)
{
D3D11ES2FormatInfo d3d11FormatInfo;
if (getD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mSRVFormat;
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
else if (clientVersion == 3)
{
D3D11ES3FormatInfo d3d11FormatInfo;
if (getD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mSRVFormat;
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
DXGI_FORMAT GetRTVFormat(GLint internalFormat, GLuint clientVersion)
{
if (clientVersion == 2)
{
D3D11ES2FormatInfo d3d11FormatInfo;
if (getD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mRTVFormat;
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
else if (clientVersion == 3)
{
D3D11ES3FormatInfo d3d11FormatInfo;
if (getD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mRTVFormat;
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
DXGI_FORMAT GetDSVFormat(GLint internalFormat, GLuint clientVersion)
{
if (clientVersion == 2)
{
D3D11ES2FormatInfo d3d11FormatInfo;
if (getD3D11ES2FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mDSVFormat;
}
else
{
return DXGI_FORMAT_UNKNOWN;
}
}
else if (clientVersion == 3)
{
D3D11ES3FormatInfo d3d11FormatInfo;
if (getD3D11ES3FormatInfo(internalFormat, clientVersion, &d3d11FormatInfo))
{
return d3d11FormatInfo.mDSVFormat;
}
else
{
return DXGI_FORMAT_UNKNOWN;
}
}
else
{
UNREACHABLE();
return DXGI_FORMAT_UNKNOWN;
}
}
}
namespace d3d11_gl
{
GLint GetInternalFormat(DXGI_FORMAT format)
{
static const DXGIFormatInfoMap infoMap = buildDXGIFormatInfoMap();
DXGIFormatInfoMap::const_iterator iter = infoMap.find(format);
if (iter != infoMap.end())
{
return iter->second.mInternalFormat;
}
else
{
UNREACHABLE();
return GL_NONE;
}
}
}
}
//
// Copyright (c) 2013 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.
//
// formatutils11.h: Queries for GL image formats and their translations to D3D11
// formats.
#ifndef LIBGLESV2_RENDERER_FORMATUTILS11_H_
#define LIBGLESV2_RENDERER_FORMATUTILS11_H_
#include "libGLESv2/formatutils.h"
namespace rx
{
namespace d3d11
{
MipGenerationFunction GetMipGenerationFunction(DXGI_FORMAT format);
LoadImageFunction GetImageLoadFunction(GLint internalFormat, GLenum type, GLuint clientVersion);
GLuint GetFormatPixelBytes(DXGI_FORMAT format);
GLuint GetBlockWidth(DXGI_FORMAT format);
GLuint GetBlockHeight(DXGI_FORMAT format);
void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
}
namespace gl_d3d11
{
DXGI_FORMAT GetTexFormat(GLint internalFormat, GLuint clientVersion);
DXGI_FORMAT GetSRVFormat(GLint internalFormat, GLuint clientVersion);
DXGI_FORMAT GetRTVFormat(GLint internalFormat, GLuint clientVersion);
DXGI_FORMAT GetDSVFormat(GLint internalFormat, GLuint clientVersion);
}
namespace d3d11_gl
{
GLint GetInternalFormat(DXGI_FORMAT format);
}
}
#endif // LIBGLESV2_RENDERER_FORMATUTILS11_H_
#include "precompiled.h"
//
// Copyright (c) 2013 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.
//
// formatutils9.cpp: Queries for GL image formats and their translations to D3D9
// formats.
#include "libGLESv2/renderer/formatutils9.h"
#include "libGLESv2/renderer/Renderer9.h"
#include "libGLESv2/renderer/generatemip.h"
#include "libGLESv2/renderer/loadimage.h"
namespace rx
{
// Each GL internal format corresponds to one D3D format and data loading function.
// Due to not all formats being available all the time, some of the function/format types are wrapped
// in templates that perform format support queries on a Renderer9 object which is supplied
// when requesting the function or format.
typedef bool ((Renderer9::*Renderer9FormatCheckFunction)(void) const);
typedef LoadImageFunction (*RendererCheckLoadFunction)(const Renderer9 *renderer);
template <Renderer9FormatCheckFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
LoadImageFunction RendererCheckLoad(const Renderer9 *renderer)
{
return ((renderer->*pred)()) ? prefered : fallback;
}
template <LoadImageFunction loadFunc>
LoadImageFunction SimpleLoad(const Renderer9 *renderer)
{
return loadFunc;
}
LoadImageFunction UnreachableLoad(const Renderer9 *renderer)
{
UNREACHABLE();
return NULL;
}
typedef bool (*FallbackPredicateFunction)(void);
template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
LoadImageFunction FallbackLoadFunction(const Renderer9 *renderer)
{
return pred() ? prefered : fallback;
}
typedef D3DFORMAT (*FormatQueryFunction)(const rx::Renderer9 *renderer);
template <Renderer9FormatCheckFunction pred, D3DFORMAT prefered, D3DFORMAT fallback>
D3DFORMAT CheckFormatSupport(const rx::Renderer9 *renderer)
{
return (renderer->*pred)() ? prefered : fallback;
}
template <D3DFORMAT format>
D3DFORMAT D3D9Format(const rx::Renderer9 *renderer)
{
return format;
}
struct D3D9FormatInfo
{
FormatQueryFunction mTexFormat;
FormatQueryFunction mRenderFormat;
RendererCheckLoadFunction mLoadFunction;
D3D9FormatInfo()
: mTexFormat(NULL), mRenderFormat(NULL), mLoadFunction(NULL)
{ }
D3D9FormatInfo(FormatQueryFunction textureFormat, FormatQueryFunction renderFormat, RendererCheckLoadFunction loadFunc)
: mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc)
{ }
};
const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')));
const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')));
typedef std::pair<GLint, D3D9FormatInfo> D3D9FormatPair;
typedef std::map<GLint, D3D9FormatInfo> D3D9FormatMap;
static D3D9FormatMap buildD3D9FormatMap()
{
D3D9FormatMap map;
// | Internal format | Texture format | Render format | Load function |
map.insert(D3D9FormatPair(GL_NONE, D3D9FormatInfo(D3D9Format<D3DFMT_NULL>, D3D9Format<D3DFMT_NULL>, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D32>, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad )));
map.insert(D3D9FormatPair(GL_STENCIL_INDEX8, D3D9FormatInfo(D3D9Format<D3DFMT_UNKNOWN>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); // TODO: What's the texture format?
map.insert(D3D9FormatPair(GL_RGBA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadRGBAFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_RGB32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadRGBFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_RGBA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadRGBAHalfFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_RGB16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadRGBHalfFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaHalfFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceHalfFloatDataToRGBA> )));
map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaHalfFloatDataToRGBA>)));
map.insert(D3D9FormatPair(GL_ALPHA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadAlphaDataToBGRASSE2, loadAlphaDataToBGRA>)));
map.insert(D3D9FormatPair(GL_RGB8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRGBUByteDataToBGRX> )));
map.insert(D3D9FormatPair(GL_RGB565, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_R5G6B5>, SimpleLoad<loadRGB565DataToBGRA> )));
map.insert(D3D9FormatPair(GL_RGBA8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadRGBAUByteDataToBGRASSE2, loadRGBAUByteDataToBGRA>)));
map.insert(D3D9FormatPair(GL_RGBA4, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToBGRA> )));
map.insert(D3D9FormatPair(GL_RGB5_A1, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToBGRA> )));
map.insert(D3D9FormatPair(GL_BGRA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadBGRADataToBGRA> )));
map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToRGBA> )));
map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToRGBA> )));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >)));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >)));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT3>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >)));
map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT5>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >)));
// These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
// then changing the format and loading function appropriately.
map.insert(D3D9FormatPair(GL_LUMINANCE8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceTextureSupport, D3DFMT_L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadLuminanceDataToNative, loadLuminanceDataToBGRA>)));
map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceAlphaTextureSupport, D3DFMT_A8L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadLuminanceAlphaDataToNative, loadLuminanceAlphaDataToBGRA>)));
return map;
}
static bool getD3D9FormatInfo(GLint internalFormat, D3D9FormatInfo *outFormatInfo)
{
static const D3D9FormatMap formatMap = buildD3D9FormatMap();
D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat);
if (iter != formatMap.end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
}
else
{
return false;
}
}
// A map for determining the mip map generation function given a texture's internal D3D format
typedef std::pair<D3DFORMAT, MipGenerationFunction> FormatMipPair;
typedef std::map<D3DFORMAT, MipGenerationFunction> FormatMipMap;
static FormatMipMap buildFormatMipMap()
{
FormatMipMap map;
// | D3DFORMAT | Mip generation function |
map.insert(FormatMipPair(D3DFMT_L8, GenerateMip<L8> ));
map.insert(FormatMipPair(D3DFMT_A8L8, GenerateMip<A8L8> ));
map.insert(FormatMipPair(D3DFMT_A8R8G8B8, GenerateMip<A8R8G8B8> ));
map.insert(FormatMipPair(D3DFMT_X8R8G8B8, GenerateMip<A8R8G8B8> ));
map.insert(FormatMipPair(D3DFMT_A16B16G16R16F, GenerateMip<A16B16G16R16F>));
map.insert(FormatMipPair(D3DFMT_A32B32G32R32F, GenerateMip<A32B32G32R32F>));
return map;
}
// A map to determine the pixel size of a given D3D format
struct D3DFormatInfo
{
GLuint mPixelBits;
GLuint mBlockWidth;
GLuint mBlockHeight;
GLint mInternalFormat;
D3DFormatInfo()
: mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE)
{ }
D3DFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLint internalFormat)
: mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat)
{ }
};
typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair;
typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap;
static D3D9FormatInfoMap buildD3D9FormatInfoMap()
{
D3D9FormatInfoMap map;
// | D3DFORMAT | | S |W |H | Internal format |
map.insert(D3D9FormatInfoPair(D3DFMT_NULL, D3DFormatInfo( 0, 0, 0, GL_NONE )));
map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN, D3DFormatInfo( 0, 0, 0, GL_NONE )));
map.insert(D3D9FormatInfoPair(D3DFMT_L8, D3DFormatInfo( 8, 1, 1, GL_LUMINANCE8_EXT )));
map.insert(D3D9FormatInfoPair(D3DFMT_A8, D3DFormatInfo( 8, 1, 1, GL_ALPHA8_EXT )));
map.insert(D3D9FormatInfoPair(D3DFMT_A8L8, D3DFormatInfo( 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT )));
map.insert(D3D9FormatInfoPair(D3DFMT_A4R4G4B4, D3DFormatInfo( 16, 1, 1, GL_RGBA4 )));
map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5, D3DFormatInfo( 16, 1, 1, GL_RGB5_A1 )));
map.insert(D3D9FormatInfoPair(D3DFMT_R5G6B5, D3DFormatInfo( 16, 1, 1, GL_RGB565 )));
map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_RGB8_OES )));
map.insert(D3D9FormatInfoPair(D3DFMT_A8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_RGBA8_OES )));
map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 64, 1, 1, GL_RGBA16F_EXT )));
map.insert(D3D9FormatInfoPair(D3DFMT_A32B32G32R32F, D3DFormatInfo(128, 1, 1, GL_RGBA32F_EXT )));
map.insert(D3D9FormatInfoPair(D3DFMT_D16, D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16 )));
map.insert(D3D9FormatInfoPair(D3DFMT_D24S8, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES )));
map.insert(D3D9FormatInfoPair(D3DFMT_D24X8, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16 )));
map.insert(D3D9FormatInfoPair(D3DFMT_D32, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES )));
map.insert(D3D9FormatInfoPair(D3DFMT_INTZ, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES )));
map.insert(D3D9FormatInfoPair(D3DFMT_DXT1, D3DFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )));
map.insert(D3D9FormatInfoPair(D3DFMT_DXT3, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)));
map.insert(D3D9FormatInfoPair(D3DFMT_DXT5, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)));
return map;
}
static bool getD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo)
{
static const D3D9FormatInfoMap infoMap = buildD3D9FormatInfoMap();
D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
if (iter != infoMap.end())
{
if (outFormatInfo)
{
*outFormatInfo = iter->second;
}
return true;
}
else
{
return false;
}
}
namespace d3d9
{
MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format)
{
static const FormatMipMap mipFunctionMap = buildFormatMipMap();
FormatMipMap::const_iterator iter = mipFunctionMap.find(format);
if (iter != mipFunctionMap.end())
{
return iter->second;
}
else
{
UNREACHABLE();
return NULL;
}
}
LoadImageFunction GetImageLoadFunction(GLint internalFormat, const Renderer9 *renderer)
{
if (!renderer)
{
return NULL;
}
ASSERT(renderer->getCurrentClientVersion() == 2);
D3D9FormatInfo d3d9FormatInfo;
if (getD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
{
return d3d9FormatInfo.mLoadFunction(renderer);
}
else
{
UNREACHABLE();
return NULL;
}
}
GLuint GetFormatPixelBytes(D3DFORMAT format)
{
D3DFormatInfo d3dFormatInfo;
if (getD3D9FormatInfo(format, &d3dFormatInfo))
{
return d3dFormatInfo.mPixelBits / 8;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlockWidth(D3DFORMAT format)
{
D3DFormatInfo d3dFormatInfo;
if (getD3D9FormatInfo(format, &d3dFormatInfo))
{
return d3dFormatInfo.mBlockWidth;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlockHeight(D3DFORMAT format)
{
D3DFormatInfo d3dFormatInfo;
if (getD3D9FormatInfo(format, &d3dFormatInfo))
{
return d3dFormatInfo.mBlockHeight;
}
else
{
UNREACHABLE();
return 0;
}
}
GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height)
{
D3DFormatInfo d3dFormatInfo;
if (getD3D9FormatInfo(format, &d3dFormatInfo))
{
GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth;
GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight;
return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
}
else
{
UNREACHABLE();
return 0;
}
}
void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
{
D3DFormatInfo d3dFormatInfo;
if (getD3D9FormatInfo(format, &d3dFormatInfo))
{
int upsampleCount = 0;
GLsizei blockWidth = d3dFormatInfo.mBlockWidth;
GLsizei blockHeight = d3dFormatInfo.mBlockHeight;
// Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight)
{
while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0)
{
*requestWidth <<= 1;
*requestHeight <<= 1;
upsampleCount++;
}
}
*levelOffset = upsampleCount;
}
}
}
namespace gl_d3d9
{
D3DFORMAT GetTexureFormat(GLint internalFormat, const Renderer9 *renderer)
{
if (!renderer)
{
UNREACHABLE();
return D3DFMT_UNKNOWN;
}
ASSERT(renderer->getCurrentClientVersion() == 2);
D3D9FormatInfo d3d9FormatInfo;
if (getD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
{
return d3d9FormatInfo.mTexFormat(renderer);
}
else
{
UNREACHABLE();
return D3DFMT_UNKNOWN;
}
}
D3DFORMAT GetRenderFormat(GLint internalFormat, const Renderer9 *renderer)
{
if (!renderer)
{
UNREACHABLE();
return D3DFMT_UNKNOWN;
}
ASSERT(renderer->getCurrentClientVersion() == 2);
D3D9FormatInfo d3d9FormatInfo;
if (getD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
{
return d3d9FormatInfo.mRenderFormat(renderer);
}
else
{
UNREACHABLE();
return D3DFMT_UNKNOWN;
}
}
D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples)
{
return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE;
}
}
namespace d3d9_gl
{
GLint GetInternalFormat(D3DFORMAT format)
{
static const D3D9FormatInfoMap infoMap = buildD3D9FormatInfoMap();
D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
if (iter != infoMap.end())
{
return iter->second.mInternalFormat;
}
else
{
UNREACHABLE();
return GL_NONE;
}
}
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
{
return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
}
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion)
{
GLint internalFormat = d3d9_gl::GetInternalFormat(d3dformat);
GLenum convertedFormat = gl::GetFormat(internalFormat, clientVersion);
return convertedFormat == format;
}
}
}
//
// Copyright (c) 2013 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.
//
// formatutils9.h: Queries for GL image formats and their translations to D3D9
// formats.
#ifndef LIBGLESV2_RENDERER_FORMATUTILS9_H_
#define LIBGLESV2_RENDERER_FORMATUTILS9_H_
#include "libGLESv2/formatutils.h"
namespace rx
{
class Renderer9;
namespace d3d9
{
MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format);
LoadImageFunction GetImageLoadFunction(GLint internalFormat, const Renderer9 *renderer);
GLuint GetFormatPixelBytes(D3DFORMAT format);
GLuint GetBlockWidth(D3DFORMAT format);
GLuint GetBlockHeight(D3DFORMAT format);
GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height);
void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
}
namespace gl_d3d9
{
D3DFORMAT GetTexureFormat(GLint internalFormat, const Renderer9 *renderer);
D3DFORMAT GetRenderFormat(GLint internalFormat, const Renderer9 *renderer);
D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples);
}
namespace d3d9_gl
{
GLint GetInternalFormat(D3DFORMAT format);
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type);
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion);
}
}
#endif // LIBGLESV2_RENDERER_FORMATUTILS9_H_
...@@ -54,6 +54,7 @@ struct A8R8G8B8 ...@@ -54,6 +54,7 @@ struct A8R8G8B8
}; };
typedef A8R8G8B8 R8G8B8A8; // R8G8B8A8 type is functionally equivalent for mip purposes typedef A8R8G8B8 R8G8B8A8; // R8G8B8A8 type is functionally equivalent for mip purposes
typedef A8R8G8B8 B8G8R8A8; // B8G8R8A8 type is functionally equivalent for mip purposes
struct A16B16G16R16F struct A16B16G16R16F
{ {
...@@ -93,6 +94,8 @@ struct R16G16F ...@@ -93,6 +94,8 @@ struct R16G16F
} }
}; };
typedef A16B16G16R16F R16G16B16A16F;
struct A32B32G32R32F struct A32B32G32R32F
{ {
float R; float R;
...@@ -145,6 +148,11 @@ struct R32G32B32F ...@@ -145,6 +148,11 @@ struct R32G32B32F
} }
}; };
typedef A32B32G32R32F R32G32B32A32F;
namespace priv
{
template <typename T> template <typename T>
static inline T *GetPixel(void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch) static inline T *GetPixel(void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch)
{ {
...@@ -346,6 +354,7 @@ static void GenerateMip_XYZ(unsigned int sourceWidth, unsigned int sourceHeight, ...@@ -346,6 +354,7 @@ static void GenerateMip_XYZ(unsigned int sourceWidth, unsigned int sourceHeight,
} }
} }
typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
unsigned int destWidth, unsigned int destHeight, unsigned int destDepth, unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
...@@ -371,6 +380,8 @@ static MipGenerationFunction GetMipGenerationFunction(unsigned int sourceWidth, ...@@ -371,6 +380,8 @@ static MipGenerationFunction GetMipGenerationFunction(unsigned int sourceWidth,
} }
} }
}
template <typename T> template <typename T>
static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth, static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch, const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
...@@ -380,7 +391,7 @@ static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, uns ...@@ -380,7 +391,7 @@ static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, uns
unsigned int mipHeight = std::max(1U, sourceHeight >> 1); unsigned int mipHeight = std::max(1U, sourceHeight >> 1);
unsigned int mipDepth = std::max(1U, sourceDepth >> 1); unsigned int mipDepth = std::max(1U, sourceDepth >> 1);
MipGenerationFunction generationFunction = GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth); priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth);
ASSERT(generationFunction != NULL); ASSERT(generationFunction != NULL);
generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch, generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch,
......
#include "precompiled.h"
//
// Copyright (c) 0013 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.
//
// loadimage.cpp: Defines image loading functions.
#include "libGLESv2/renderer/loadimage.h"
namespace rx
{
template <typename T>
inline static T *offsetDataPointer(void *data, int y, int z, int rowPitch, int depthPitch)
{
return reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(data) + (y * rowPitch) + (z * depthPitch));
}
template <typename T>
inline static const T *offsetDataPointer(const void *data, int y, int z, int rowPitch, int depthPitch)
{
return reinterpret_cast<const T*>(reinterpret_cast<const unsigned char*>(data) + (y * rowPitch) + (z * depthPitch));
}
void loadAlphaDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
dest[4 * x + 1] = 0;
dest[4 * x + 2] = 0;
dest[4 * x + 3] = source[x];
}
}
}
}
void loadAlphaDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width);
}
}
}
void loadAlphaFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const float *source = NULL;
float *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
dest[4 * x + 1] = 0;
dest[4 * x + 2] = 0;
dest[4 * x + 3] = source[x];
}
}
}
}
void loadAlphaHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = 0;
dest[4 * x + 1] = 0;
dest[4 * x + 2] = 0;
dest[4 * x + 3] = source[x];
}
}
}
}
void loadLuminanceDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width);
}
}
}
void loadLuminanceDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
dest[4 * x + 1] = source[x];
dest[4 * x + 2] = source[x];
dest[4 * x + 3] = 0xFF;
}
}
}
}
void loadLuminanceFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const float *source = NULL;
float *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
dest[4 * x + 1] = source[x];
dest[4 * x + 2] = source[x];
dest[4 * x + 3] = 1.0f;
}
}
}
}
void loadLuminanceFloatDataToRGB(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const float *source = NULL;
float *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[3 * x + 0] = source[x];
dest[3 * x + 1] = source[x];
dest[3 * x + 2] = source[x];
}
}
}
}
void loadLuminanceHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x];
dest[4 * x + 1] = source[x];
dest[4 * x + 2] = source[x];
dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
}
}
}
}
void loadLuminanceAlphaDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width * 2);
}
}
}
void loadLuminanceAlphaDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
dest[4 * x + 1] = source[2*x+0];
dest[4 * x + 2] = source[2*x+0];
dest[4 * x + 3] = source[2*x+1];
}
}
}
}
void loadLuminanceAlphaFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const float *source = NULL;
float *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
dest[4 * x + 1] = source[2*x+0];
dest[4 * x + 2] = source[2*x+0];
dest[4 * x + 3] = source[2*x+1];
}
}
}
}
void loadLuminanceAlphaHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
dest[4 * x + 1] = source[2*x+0];
dest[4 * x + 2] = source[2*x+0];
dest[4 * x + 3] = source[2*x+1];
}
}
}
}
void loadRGBUByteDataToBGRX(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 2];
dest[4 * x + 1] = source[x * 3 + 1];
dest[4 * x + 2] = source[x * 3 + 0];
dest[4 * x + 3] = 0xFF;
}
}
}
}
void loadRGBUByteDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 0];
dest[4 * x + 1] = source[x * 3 + 1];
dest[4 * x + 2] = source[x * 3 + 2];
dest[4 * x + 3] = 0xFF;
}
}
}
}
void loadRGB565DataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
dest[4 * x + 3] = 0xFF;
}
}
}
}
void loadRGB565DataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
dest[4 * x + 2] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
dest[4 * x + 3] = 0xFF;
}
}
}
}
void loadRGBFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const float *source = NULL;
float *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 0];
dest[4 * x + 1] = source[x * 3 + 1];
dest[4 * x + 2] = source[x * 3 + 2];
dest[4 * x + 3] = 1.0f;
}
}
}
}
void loadRGBFloatDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const float *source = NULL;
float *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width * 12);
}
}
}
void loadRGBHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned short *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned short>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[x * 3 + 0];
dest[4 * x + 1] = source[x * 3 + 1];
dest[4 * x + 2] = source[x * 3 + 2];
dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
}
}
}
}
void loadRGBAUByteDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned int *source = NULL;
unsigned int *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
unsigned int rgba = source[x];
dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
}
}
}
}
void loadRGBAUByteDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned int *source = NULL;
unsigned int *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned int>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned int>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width * 4);
}
}
}
void loadRGBA4444DataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
}
}
}
}
void loadRGBA4444DataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
}
}
}
}
void loadRGBA5551DataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
}
}
}
}
void loadRGBA5551DataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned short *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned short>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
for (int x = 0; x < width; x++)
{
unsigned short rgba = source[x];
dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
}
}
}
}
void loadRGBAFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const float *source = NULL;
float *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width * 16);
}
}
}
void loadRGBAHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width * 8);
}
}
}
void loadBGRADataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned char *dest = NULL;
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = offsetDataPointer<unsigned char>(input, y, z, inputRowPitch, inputDepthPitch);
dest = offsetDataPointer<unsigned char>(output, y, z, outputRowPitch, outputDepthPitch);
memcpy(dest, source, width*4);
}
}
}
}
//
// Copyright (c) 2013 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.
//
// loadimage.h: Defines image loading functions
#ifndef LIBGLESV2_RENDERER_LOADIMAGE_H_
#define LIBGLESV2_RENDERER_LOADIMAGE_H_
namespace rx
{
void loadAlphaDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadAlphaDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadAlphaDataToBGRASSE2(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadAlphaFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadAlphaHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceFloatDataToRGB(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceAlphaDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceAlphaDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceAlphaFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadLuminanceAlphaHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBUByteDataToBGRX(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBUByteDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGB565DataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGB565DataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBFloatDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBAUByteDataToBGRASSE2(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBAUByteDataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBAUByteDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBA4444DataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBA4444DataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBA5551DataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBA5551DataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBAFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadRGBAHalfFloatDataToRGBA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
void loadBGRADataToBGRA(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch);
template <unsigned int blockWidth, unsigned int blockHeight, unsigned int blockSize>
void loadCompressedBlockDataToNative(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
int columns = (width + (blockWidth - 1)) / blockWidth;
int rows = (height + (blockHeight - 1)) / blockHeight;
for (int z = 0; z < depth; ++z)
{
for (int y = 0; y < rows; ++y)
{
void *source = (void*)((char*)input + y * inputRowPitch + z * inputDepthPitch);
void *dest = (void*)((char*)output + y * outputRowPitch + z * outputDepthPitch);
memcpy(dest, source, columns * blockSize);
}
}
}
}
#endif // LIBGLESV2_RENDERER_LOADIMAGE_H_
#include "precompiled.h"
//
// Copyright (c) 2002-2012 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.
//
// loadimage.cpp: Defines image loading functions. It's
// in a separated file for GCC, which can enable SSE usage only per-file,
// not for code blocks that use SSE2 explicitly.
#include "libGLESv2/renderer/loadimage.h"
namespace rx
{
void loadAlphaDataToBGRASSE2(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned char *source = NULL;
unsigned int *dest = NULL;
__m128i zeroWide = _mm_setzero_si128();
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = static_cast<const unsigned char*>(input) + y * inputRowPitch + z * inputDepthPitch;
dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputRowPitch + z * outputDepthPitch);
int x;
// Make output writes aligned
for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++)
{
dest[x] = static_cast<unsigned int>(source[x]) << 24;
}
for (; x + 7 < width; x += 8)
{
__m128i sourceData = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&source[x]));
// Interleave each byte to 16bit, make the lower byte to zero
sourceData = _mm_unpacklo_epi8(zeroWide, sourceData);
// Interleave each 16bit to 32bit, make the lower 16bit to zero
__m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData);
__m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData);
_mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo);
_mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi);
}
// Handle the remainder
for (; x < width; x++)
{
dest[x] = static_cast<unsigned int>(source[x]) << 24;
}
}
}
}
void loadRGBAUByteDataToBGRASSE2(int width, int height, int depth,
const void *input, unsigned int inputRowPitch, unsigned int inputDepthPitch,
void *output, unsigned int outputRowPitch, unsigned int outputDepthPitch)
{
const unsigned int *source = NULL;
unsigned int *dest = NULL;
__m128i brMask = _mm_set1_epi32(0x00ff00ff);
for (int z = 0; z < depth; z++)
{
for (int y = 0; y < height; y++)
{
source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputRowPitch + z * inputDepthPitch);
dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputRowPitch + z * outputDepthPitch);
int x = 0;
// Make output writes aligned
for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++)
{
unsigned int rgba = source[x];
dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
}
for (; x + 3 < width; x += 4)
{
__m128i sourceData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&source[x]));
// Mask out g and a, which don't change
__m128i gaComponents = _mm_andnot_si128(brMask, sourceData);
// Mask out b and r
__m128i brComponents = _mm_and_si128(sourceData, brMask);
// Swap b and r
__m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1));
__m128i result = _mm_or_si128(gaComponents, brSwapped);
_mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result);
}
// Perform leftover writes
for (; x < width; x++)
{
unsigned int rgba = source[x];
dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment