Commit b5e346f5 by Nicolas Capens

Validate internalformat and combinations.

Change-Id: Ibd2c6ae673be34e7a6e701454261f25658d1df22 Reviewed-on: https://swiftshader-review.googlesource.com/5122Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 8bcd9dd9
......@@ -38,15 +38,6 @@
namespace es2
{
typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
// A helper function to insert data into the format map with fewer characters.
static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
{
map[InternalFormatTypePair(internalformat, type)] = format;
}
static bool validImageSize(GLint level, GLsizei width, GLsizei height)
{
if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
......@@ -118,108 +109,6 @@ static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFo
return true;
}
static FormatMap BuildFormatMap3D()
{
FormatMap map;
// Internal format | Format | Type
InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_R8_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT);
InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
InsertFormatMapping(map, GL_R32F_EXT, GL_RED_EXT, GL_FLOAT);
InsertFormatMapping(map, GL_RG8_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT);
InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
InsertFormatMapping(map, GL_RG32F_EXT, GL_RG_EXT, GL_FLOAT);
InsertFormatMapping(map, GL_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_SRGB8_NV, GL_RGB, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT);
InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_FLOAT);
InsertFormatMapping(map, GL_RGB32F_EXT, GL_RGB, GL_FLOAT);
InsertFormatMapping(map, GL_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
InsertFormatMapping(map, GL_RGB10_A2_EXT, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT);
InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_FLOAT);
InsertFormatMapping(map, GL_RGBA32F_EXT, GL_RGBA, GL_FLOAT);
return map;
}
static bool ValidateType3D(GLenum type)
{
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_INT:
case GL_INT:
case GL_HALF_FLOAT:
case GL_HALF_FLOAT_OES:
case GL_FLOAT:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
return true;
default:
break;
}
return false;
}
static bool ValidateFormat3D(GLenum format)
{
switch(format)
{
case GL_RED_EXT:
case GL_RG_EXT:
case GL_RGB:
case GL_RGBA:
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
case GL_LUMINANCE_ALPHA:
case GL_LUMINANCE:
case GL_ALPHA:
return true;
default:
break;
}
return false;
}
static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
{
static const FormatMap formatMap = BuildFormatMap3D();
FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
if(iter != formatMap.end())
{
return iter->second == format;
}
return false;
}
void ActiveTexture(GLenum texture)
{
TRACE("(GLenum texture = 0x%X)", texture);
......@@ -5155,667 +5044,9 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
return error(validationError);
}
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_FLOAT: // GL_OES_texture_float
case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float
case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil
case GL_UNSIGNED_SHORT: // GL_OES_depth_texture
case GL_UNSIGNED_INT: // GL_OES_depth_texture
break;
case GL_BYTE:
case GL_SHORT:
case GL_INT:
case GL_HALF_FLOAT:
case GL_UNSIGNED_INT_2_10_10_10_REV:
case GL_UNSIGNED_INT_10F_11F_11F_REV:
case GL_UNSIGNED_INT_5_9_9_9_REV:
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
if(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
break;
default:
return error(GL_INVALID_ENUM);
}
switch(format)
if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
{
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
switch(type)
{
case GL_HALF_FLOAT:
case GL_UNSIGNED_BYTE:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RED:
switch(internalformat)
{
case GL_R8:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R8_SNORM:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R16F:
switch(type)
{
case GL_HALF_FLOAT:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R32F:
switch(type)
{
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_RED_INTEGER:
switch(internalformat)
{
case GL_R8UI:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R8I:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R16UI:
switch(type)
{
case GL_UNSIGNED_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R16I:
switch(type)
{
case GL_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R32UI:
switch(type)
{
case GL_UNSIGNED_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R32I:
switch(type)
{
case GL_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_RG_INTEGER:
switch(internalformat)
{
case GL_RG8UI:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG8I:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG16UI:
switch(type)
{
case GL_UNSIGNED_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG16I:
switch(type)
{
case GL_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG32UI:
switch(type)
{
case GL_UNSIGNED_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG32I:
switch(type)
{
case GL_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_RGB_INTEGER:
switch(internalformat)
{
case GL_RGB8UI:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB8I:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB16UI:
switch(type)
{
case GL_UNSIGNED_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB16I:
switch(type)
{
case GL_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB32UI:
switch(type)
{
case GL_UNSIGNED_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB32I:
switch(type)
{
case GL_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_RGBA_INTEGER:
switch(internalformat)
{
case GL_RGBA8UI:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA8I:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB10_A2UI:
switch(type)
{
case GL_UNSIGNED_INT_2_10_10_10_REV:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA16UI:
switch(type)
{
case GL_UNSIGNED_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA16I:
switch(type)
{
case GL_SHORT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA32UI:
switch(type)
{
case GL_UNSIGNED_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA32I:
switch(type)
{
case GL_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_RG:
switch(internalformat)
{
case GL_RG8:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG8_SNORM:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG16F:
switch(type)
{
case GL_HALF_FLOAT:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RG32F:
switch(type)
{
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_RGB:
switch(internalformat)
{
case GL_RGB:
switch(type)
{
case GL_HALF_FLOAT:
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB8:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_SRGB8:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB565:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB8_SNORM:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_R11F_G11F_B10F:
switch(type)
{
case GL_HALF_FLOAT:
case GL_UNSIGNED_INT_10F_11F_11F_REV:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB9_E5:
switch(type)
{
case GL_HALF_FLOAT:
case GL_UNSIGNED_INT_5_9_9_9_REV:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB16F:
switch(type)
{
case GL_HALF_FLOAT:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB32F:
switch(type)
{
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_RGBA:
switch(internalformat)
{
case GL_RGBA:
switch(type)
{
case GL_HALF_FLOAT:
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA8:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_SRGB8_ALPHA8:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB5_A1:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_INT_2_10_10_10_REV:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA8_SNORM:
switch(type)
{
case GL_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA4:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGB10_A2:
switch(type)
{
case GL_UNSIGNED_INT_2_10_10_10_REV:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA16F:
switch(type)
{
case GL_HALF_FLOAT:
case GL_FLOAT:
case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA32F:
switch(type)
{
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_BGRA_EXT:
switch(type)
{
case GL_UNSIGNED_BYTE:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_DEPTH_COMPONENT:
switch(internalformat)
{
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
switch(type)
{
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES:
switch(type)
{
case GL_UNSIGNED_INT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_DEPTH_COMPONENT32F:
switch(type)
{
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
case GL_DEPTH_STENCIL_OES:
switch(internalformat)
{
case GL_DEPTH_STENCIL_OES:
case GL_DEPTH24_STENCIL8:
switch(type)
{
case GL_UNSIGNED_INT_24_8_OES:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
case GL_DEPTH32F_STENCIL8:
switch(type)
{
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
break;
default:
return error(GL_INVALID_OPERATION);
}
break;
default:
return error(GL_INVALID_VALUE);
}
break;
default:
return error(GL_INVALID_VALUE);
return;
}
if(border != 0)
......@@ -6206,7 +5437,7 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
return error(GL_INVALID_VALUE);
}
if(!es2::ValidateTextureFormatType(format, type, egl::getClientVersion()))
if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
{
return;
}
......@@ -7028,9 +6259,9 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi
return error(GL_INVALID_ENUM);
}
if(!ValidateType3D(type) || !ValidateFormat3D(format))
if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
{
return error(GL_INVALID_ENUM);
return;
}
if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
......@@ -7049,11 +6280,6 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi
return error(GL_INVALID_VALUE);
}
if(!ValidateInternalFormat3D(internalformat, format, type))
{
return error(GL_INVALID_OPERATION);
}
es2::Context *context = es2::getContext();
if(context)
......@@ -7084,9 +6310,9 @@ void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset,
return error(GL_INVALID_ENUM);
}
if(!ValidateType3D(type) || !ValidateFormat3D(format))
if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
{
return error(GL_INVALID_ENUM);
return;
}
if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
......
......@@ -703,7 +703,7 @@ namespace es2
return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
}
bool ValidateTextureFormatType(GLenum format, GLenum type, GLint clientVersion)
bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)
{
switch(type)
{
......@@ -760,116 +760,195 @@ namespace es2
return error(GL_INVALID_ENUM, false);
}
if(internalformat != format)
{
if(clientVersion < 3)
{
return error(GL_INVALID_OPERATION, false);
}
switch(internalformat)
{
case GL_R8:
case GL_R8UI:
case GL_R8I:
case GL_R16UI:
case GL_R16I:
case GL_R32UI:
case GL_R32I:
case GL_RG8:
case GL_RG8UI:
case GL_RG8I:
case GL_RG16UI:
case GL_RG16I:
case GL_RG32UI:
case GL_RG32I:
case GL_SRGB8_ALPHA8:
case GL_RGB8UI:
case GL_RGB8I:
case GL_RGB16UI:
case GL_RGB16I:
case GL_RGB32UI:
case GL_RGB32I:
case GL_RG8_SNORM:
case GL_R8_SNORM:
case GL_RGB10_A2:
case GL_RGBA8UI:
case GL_RGBA8I:
case GL_RGB10_A2UI:
case GL_RGBA16UI:
case GL_RGBA16I:
case GL_RGBA32I:
case GL_RGBA32UI:
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
case GL_RGB8_OES:
case GL_RGBA8_OES:
case GL_R16F:
case GL_RG16F:
case GL_R11F_G11F_B10F:
case GL_RGB16F:
case GL_RGBA16F:
case GL_R32F:
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_COMPONENT32F:
case GL_DEPTH32F_STENCIL8:
case GL_DEPTH_COMPONENT16:
case GL_STENCIL_INDEX8:
case GL_DEPTH24_STENCIL8_OES:
case GL_RGBA8_SNORM:
case GL_SRGB8:
case GL_RGB8_SNORM:
case GL_RGB9_E5:
break;
default:
return error(GL_INVALID_ENUM, false);
}
}
// Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2]
bool validSizedInternalformat = false;
#define VALIDATE_INTERNALFORMAT(...) { GLenum validInternalformats[] = {__VA_ARGS__}; for(GLenum v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break;
switch(format)
{
case GL_RGBA:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_HALF_FLOAT_OES:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_INT_2_10_10_10_REV:
case GL_HALF_FLOAT:
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
case GL_HALF_FLOAT_OES: break;
case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4)
case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_RGBA_INTEGER:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_INT:
case GL_INT:
case GL_UNSIGNED_INT_2_10_10_10_REV:
break;
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8I)
case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I)
case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_RGB:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_HALF_FLOAT_OES:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_INT_10F_11F_11F_REV:
case GL_UNSIGNED_INT_5_9_9_9_REV:
case GL_HALF_FLOAT:
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
case GL_HALF_FLOAT_OES: break;
case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565)
case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
case GL_UNSIGNED_INT_5_9_9_9_REV: VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_RGB_INTEGER:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_INT:
case GL_INT:
case GL_UNSIGNED_INT_2_10_10_10_REV:
break;
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8UI)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8I)
case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_RG:
case GL_RED:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_HALF_FLOAT:
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_RG_INTEGER:
switch(type)
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8UI)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8I)
case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI)
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RG32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RG32I)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_RED:
switch(type)
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8_SNORM)
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_R16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_RED_INTEGER:
switch(type)
{
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_INT:
case GL_INT:
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8UI)
case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8I)
case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_DEPTH_COMPONENT:
switch(type)
{
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
break;
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_DEPTH_STENCIL:
switch(type)
{
case GL_UNSIGNED_INT_24_8:
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
break;
default:
return error(GL_INVALID_OPERATION, false);
case GL_UNSIGNED_INT_24_8: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
default: return error(GL_INVALID_OPERATION, false);
}
break;
case GL_LUMINANCE_ALPHA:
......@@ -896,6 +975,13 @@ namespace es2
return error(GL_INVALID_ENUM, false);
}
#undef VALIDATE_INTERNALFORMAT
if(internalformat != format && !validSizedInternalformat)
{
return error(GL_INVALID_OPERATION, false);
}
return true;
}
......
......@@ -51,7 +51,7 @@ namespace es2
bool IsCubemapTextureTarget(GLenum target);
int CubeFaceIndex(GLenum cubeTarget);
bool IsTextureTarget(GLenum target);
bool ValidateTextureFormatType(GLenum format, GLenum type, GLint clientVersion);
bool ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion);
bool IsColorRenderable(GLenum internalformat, GLint clientVersion);
bool IsDepthRenderable(GLenum internalformat);
......
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