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 @@ ...@@ -38,15 +38,6 @@
namespace es2 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) static bool validImageSize(GLint level, GLsizei width, GLsizei height)
{ {
if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0) if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
...@@ -118,108 +109,6 @@ static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFo ...@@ -118,108 +109,6 @@ static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFo
return true; 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) void ActiveTexture(GLenum texture)
{ {
TRACE("(GLenum texture = 0x%X)", texture); TRACE("(GLenum texture = 0x%X)", texture);
...@@ -5155,667 +5044,9 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, ...@@ -5155,667 +5044,9 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
return error(validationError); return error(validationError);
} }
switch(type) if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
{
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)
{ {
case GL_ALPHA: return;
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);
} }
if(border != 0) if(border != 0)
...@@ -6206,7 +5437,7 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs ...@@ -6206,7 +5437,7 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if(!es2::ValidateTextureFormatType(format, type, egl::getClientVersion())) if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
{ {
return; return;
} }
...@@ -7028,9 +6259,9 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi ...@@ -7028,9 +6259,9 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi
return error(GL_INVALID_ENUM); 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)) if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
...@@ -7049,11 +6280,6 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi ...@@ -7049,11 +6280,6 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if(!ValidateInternalFormat3D(internalformat, format, type))
{
return error(GL_INVALID_OPERATION);
}
es2::Context *context = es2::getContext(); es2::Context *context = es2::getContext();
if(context) if(context)
...@@ -7084,9 +6310,9 @@ void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, ...@@ -7084,9 +6310,9 @@ void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset,
return error(GL_INVALID_ENUM); 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)) if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
......
...@@ -703,7 +703,7 @@ namespace es2 ...@@ -703,7 +703,7 @@ namespace es2
return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY; 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) switch(type)
{ {
...@@ -760,116 +760,195 @@ namespace es2 ...@@ -760,116 +760,195 @@ namespace es2
return error(GL_INVALID_ENUM, false); 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) switch(format)
{ {
case GL_RGBA: case GL_RGBA:
switch(type) switch(type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8)
case GL_BYTE: case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM)
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES: break;
case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4)
case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1)
case GL_UNSIGNED_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1)
case GL_HALF_FLOAT: case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA16F)
case GL_FLOAT: case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
break; default: return error(GL_INVALID_OPERATION, false);
default:
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_RGBA_INTEGER: case GL_RGBA_INTEGER:
switch(type) switch(type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8UI)
case GL_BYTE: case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8I)
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16UI)
case GL_SHORT: case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16I)
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
case GL_INT: case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I)
case GL_UNSIGNED_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
break; default: return error(GL_INVALID_OPERATION, false);
default:
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_RGB: case GL_RGB:
switch(type) switch(type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8)
case GL_BYTE: case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM)
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES: break;
case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565)
case GL_UNSIGNED_INT_10F_11F_11F_REV: case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F)
case GL_UNSIGNED_INT_5_9_9_9_REV: case GL_UNSIGNED_INT_5_9_9_9_REV: VALIDATE_INTERNALFORMAT(GL_RGB9_E5)
case GL_HALF_FLOAT: case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
case GL_FLOAT: case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
break; default: return error(GL_INVALID_OPERATION, false);
default:
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_RGB_INTEGER: case GL_RGB_INTEGER:
switch(type) switch(type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8UI)
case GL_BYTE: case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8I)
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI)
case GL_SHORT: case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I)
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI)
case GL_INT: case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I)
case GL_UNSIGNED_INT_2_10_10_10_REV: default: return error(GL_INVALID_OPERATION, false);
break;
default:
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_RG: case GL_RG:
case GL_RED:
switch(type) switch(type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8)
case GL_BYTE: case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8_SNORM)
case GL_HALF_FLOAT: case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F)
case GL_FLOAT: case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
break; default: return error(GL_INVALID_OPERATION, false);
default:
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_RG_INTEGER: 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: case GL_RED_INTEGER:
switch(type) switch(type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8UI)
case GL_BYTE: case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8I)
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI)
case GL_SHORT: case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I)
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI)
case GL_INT: case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I)
default: default: return error(GL_INVALID_OPERATION, false);
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT:
switch(type) switch(type)
{ {
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
case GL_FLOAT: case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
break; default: return error(GL_INVALID_OPERATION, false);
default:
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_DEPTH_STENCIL: case GL_DEPTH_STENCIL:
switch(type) switch(type)
{ {
case GL_UNSIGNED_INT_24_8: case GL_UNSIGNED_INT_24_8: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8)
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
break; default: return error(GL_INVALID_OPERATION, false);
default:
return error(GL_INVALID_OPERATION, false);
} }
break; break;
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
...@@ -896,6 +975,13 @@ namespace es2 ...@@ -896,6 +975,13 @@ namespace es2
return error(GL_INVALID_ENUM, false); return error(GL_INVALID_ENUM, false);
} }
#undef VALIDATE_INTERNALFORMAT
if(internalformat != format && !validSizedInternalformat)
{
return error(GL_INVALID_OPERATION, false);
}
return true; return true;
} }
......
...@@ -51,7 +51,7 @@ namespace es2 ...@@ -51,7 +51,7 @@ namespace es2
bool IsCubemapTextureTarget(GLenum target); bool IsCubemapTextureTarget(GLenum target);
int CubeFaceIndex(GLenum cubeTarget); int CubeFaceIndex(GLenum cubeTarget);
bool IsTextureTarget(GLenum target); 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 IsColorRenderable(GLenum internalformat, GLint clientVersion);
bool IsDepthRenderable(GLenum internalformat); 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