Commit d2faaa99 by Nicolas Capens Committed by Nicolas Capens

Fix internalformat handling.

- Use internalformat parameter if valid, instead of deriving from format/type parameters. - Validate format/type/internalformat parameters in CopyTexSubImage(). - Moved early-out optimizations after validation. - Removed duplicate validation. - Use GLint consistently for internalformat parameters. Change-Id: I377c6bb5381602d13d281f19985aa4f11d201099 Reviewed-on: https://swiftshader-review.googlesource.com/14488Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 05bcbe6b
...@@ -328,7 +328,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples) ...@@ -328,7 +328,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
if(IsRenderbuffer(mColorbufferType[i])) if(IsRenderbuffer(mColorbufferType[i]))
{ {
if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion(), false)) if(!IsColorRenderable(colorbuffer->getFormat(), egl::getClientVersion()))
{ {
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
} }
...@@ -337,7 +337,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples) ...@@ -337,7 +337,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
{ {
GLenum format = colorbuffer->getFormat(); GLenum format = colorbuffer->getFormat();
if(!IsColorRenderable(format, egl::getClientVersion(), true)) if(!IsColorRenderable(format, egl::getClientVersion()))
{ {
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
} }
......
...@@ -431,22 +431,7 @@ void Texture::subImage(egl::Context *context, GLint xoffset, GLint yoffset, GLin ...@@ -431,22 +431,7 @@ void Texture::subImage(egl::Context *context, GLint xoffset, GLint yoffset, GLin
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth()) if(pixels && width > 0 && height > 0 && depth > 0)
{
return error(GL_INVALID_VALUE);
}
if(IsCompressed(image->getFormat(), egl::getClientVersion()))
{
return error(GL_INVALID_OPERATION);
}
if(format != image->getFormat())
{
return error(GL_INVALID_OPERATION);
}
if(pixels)
{ {
image->loadImageData(context, xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels); image->loadImageData(context, xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels);
} }
...@@ -459,16 +444,6 @@ void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GL ...@@ -459,16 +444,6 @@ void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GL
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight() || depth + zoffset > image->getDepth())
{
return error(GL_INVALID_VALUE);
}
if(format != image->getFormat())
{
return error(GL_INVALID_OPERATION);
}
if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with egl::ComputeCompressedSize() at the API level if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with egl::ComputeCompressedSize() at the API level
{ {
image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels); image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, imageSize, pixels);
...@@ -773,28 +748,31 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -773,28 +748,31 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
egl::Image *renderTarget = source->getRenderTarget(0); if(width > 0 && height > 0)
if(!renderTarget)
{ {
ERR("Failed to retrieve the render target."); egl::Image *renderTarget = source->getRenderTarget(0);
return error(GL_OUT_OF_MEMORY);
}
Renderbuffer* renderbuffer = source->getReadColorbuffer(); if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(!renderbuffer) Renderbuffer* renderbuffer = source->getReadColorbuffer();
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect(x, y, x + width, y + height, 0); if(!renderbuffer)
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight()); {
ERR("Failed to retrieve the source colorbuffer.");
return;
}
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]); sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
renderTarget->release(); copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
renderTarget->release();
}
} }
void Texture2D::setSharedImage(egl::Image *sharedImage) void Texture2D::setSharedImage(egl::Image *sharedImage)
...@@ -1415,28 +1393,31 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -1415,28 +1393,31 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
egl::Image *renderTarget = source->getRenderTarget(0); if(width > 0 && height > 0)
if(!renderTarget)
{ {
ERR("Failed to retrieve the render target."); egl::Image *renderTarget = source->getRenderTarget(0);
return error(GL_OUT_OF_MEMORY);
}
Renderbuffer* renderbuffer = source->getReadColorbuffer(); if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(!renderbuffer) Renderbuffer* renderbuffer = source->getReadColorbuffer();
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect(x, y, x + width, y + height, 0); if(!renderbuffer)
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight()); {
ERR("Failed to retrieve the source colorbuffer.");
return;
}
copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]); sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
renderTarget->release(); copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]);
renderTarget->release();
}
} }
void TextureCubeMap::generateMipmaps() void TextureCubeMap::generateMipmaps()
...@@ -1758,28 +1739,31 @@ void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1758,28 +1739,31 @@ void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
egl::Image *renderTarget = source->getRenderTarget(0); if(width > 0 && height > 0)
if(!renderTarget)
{ {
ERR("Failed to retrieve the render target."); egl::Image *renderTarget = source->getRenderTarget(0);
return error(GL_OUT_OF_MEMORY);
}
Renderbuffer* renderbuffer = source->getReadColorbuffer(); if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(!renderbuffer) Renderbuffer* renderbuffer = source->getReadColorbuffer();
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect = {x, y, x + width, y + height, 0}; if(!renderbuffer)
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight()); {
ERR("Failed to retrieve the source colorbuffer.");
return;
}
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]); sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
renderTarget->release(); copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
renderTarget->release();
}
} }
void Texture3D::setSharedImage(egl::Image *sharedImage) void Texture3D::setSharedImage(egl::Image *sharedImage)
......
...@@ -902,7 +902,6 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs ...@@ -902,7 +902,6 @@ void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLs
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{ {
GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize); GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
if(validationError != GL_NONE) if(validationError != GL_NONE)
{ {
...@@ -941,12 +940,6 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -941,12 +940,6 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
if(validationError != GL_NONE)
{
return error(validationError);
}
if(imageSize != egl::ComputeCompressedSize(width, height, format)) if(imageSize != egl::ComputeCompressedSize(width, height, format))
{ {
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
...@@ -956,11 +949,6 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -956,11 +949,6 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo
if(context) if(context)
{ {
if(imageSize != egl::ComputeCompressedSize(width, height, format))
{
return error(GL_INVALID_VALUE);
}
if(xoffset % 4 != 0 || yoffset % 4 != 0) if(xoffset % 4 != 0 || yoffset % 4 != 0)
{ {
// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
...@@ -973,41 +961,37 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -973,41 +961,37 @@ void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo
{ {
es2::Texture2D *texture = context->getTexture2D(); es2::Texture2D *texture = context->getTexture2D();
GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture); GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
if(validationError != GL_NONE)
if(validationError == GL_NONE)
{ {
validationError = context->getPixels(&data, texture->getType(target, level), imageSize); return error(validationError);
} }
if(validationError == GL_NONE) validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
{ if(validationError != GL_NONE)
texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
}
else
{ {
return error(validationError); return error(validationError);
} }
texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
} }
else if(es2::IsCubemapTextureTarget(target)) else if(es2::IsCubemapTextureTarget(target))
{ {
es2::TextureCubeMap *texture = context->getTextureCubeMap(); es2::TextureCubeMap *texture = context->getTextureCubeMap();
GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture); GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion());
if(validationError != GL_NONE)
if(validationError == GL_NONE)
{ {
validationError = context->getPixels(&data, texture->getType(target, level), imageSize); return error(validationError);
} }
if(validationError == GL_NONE) validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
{ if(validationError != GL_NONE)
texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
}
else
{ {
return error(validationError); return error(validationError);
} }
texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
} }
else UNREACHABLE(target); else UNREACHABLE(target);
} }
...@@ -1136,11 +1120,6 @@ void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ...@@ -1136,11 +1120,6 @@ void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if(width == 0 || height == 0)
{
return;
}
es2::Context *context = es2::getContext(); es2::Context *context = es2::getContext();
if(context) if(context)
...@@ -1171,7 +1150,7 @@ void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, ...@@ -1171,7 +1150,7 @@ void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
} }
else UNREACHABLE(target); else UNREACHABLE(target);
GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture); GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE, GL_NONE, texture, context->getClientVersion());
if(validationError != GL_NONE) if(validationError != GL_NONE)
{ {
return error(validationError); return error(validationError);
...@@ -4759,7 +4738,7 @@ void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum inter ...@@ -4759,7 +4738,7 @@ void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum inter
GLint clientVersion = context->getClientVersion(); GLint clientVersion = context->getClientVersion();
if(IsColorRenderable(internalformat, clientVersion, false)) if(IsColorRenderable(internalformat, clientVersion))
{ {
context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples)); context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
} }
...@@ -5102,9 +5081,10 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, ...@@ -5102,9 +5081,10 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
return error(validationError); return error(validationError);
} }
if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion())) validationError = ValidateTextureFormatType(format, type, internalformat, context->getClientVersion());
if(validationError != GL_NONE)
{ {
return; return error(validationError);
} }
if(border != 0) if(border != 0)
...@@ -5142,7 +5122,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, ...@@ -5142,7 +5122,7 @@ void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); GLenum sizedInternalFormat = GetSizedInternalFormat(internalformat, type);
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type)); validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
if(validationError != GL_NONE) if(validationError != GL_NONE)
...@@ -5501,57 +5481,47 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs ...@@ -5501,57 +5481,47 @@ void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLs
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
{
return;
}
if(width == 0 || height == 0)
{
return;
}
es2::Context *context = es2::getContext(); es2::Context *context = es2::getContext();
if(context) if(context)
{ {
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
if(validationError != GL_NONE)
{
return error(validationError);
}
if(target == GL_TEXTURE_2D) if(target == GL_TEXTURE_2D)
{ {
es2::Texture2D *texture = context->getTexture2D(); es2::Texture2D *texture = context->getTexture2D();
validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture); GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
if(validationError != GL_NONE)
if(validationError == GL_NONE)
{ {
texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data); return error(validationError);
} }
else
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
if(validationError != GL_NONE)
{ {
return error(validationError); return error(validationError);
} }
texture->subImage(context, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
} }
else if(es2::IsCubemapTextureTarget(target)) else if(es2::IsCubemapTextureTarget(target))
{ {
es2::TextureCubeMap *texture = context->getTextureCubeMap(); es2::TextureCubeMap *texture = context->getTextureCubeMap();
validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture); GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion());
if(validationError != GL_NONE)
if(validationError == GL_NONE)
{ {
texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data); return error(validationError);
} }
else
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, sizedInternalFormat, type));
if(validationError != GL_NONE)
{ {
return error(validationError); return error(validationError);
} }
texture->subImage(context, target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), data);
} }
else UNREACHABLE(target); else UNREACHABLE(target);
} }
...@@ -6349,9 +6319,15 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi ...@@ -6349,9 +6319,15 @@ void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei wi
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion())) if(internalformat != (GLint)format)
{ {
return; return error(GL_INVALID_OPERATION);
}
GLenum validationError = ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion());
if(validationError != GL_NONE)
{
return error(validationError);
} }
if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
...@@ -6430,21 +6406,19 @@ void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, ...@@ -6430,21 +6406,19 @@ void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture); GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
if(validationError != GL_NONE)
if(validationError == GL_NONE)
{ {
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type)); return error(validationError);
} }
if(validationError == GL_NONE) validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
{ if(validationError != GL_NONE)
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
}
else
{ {
return error(validationError); return error(validationError);
} }
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
} }
} }
...@@ -6487,8 +6461,7 @@ void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffs ...@@ -6487,8 +6461,7 @@ void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffs
es2::Texture3D *texture = context->getTexture3D(); es2::Texture3D *texture = context->getTexture3D();
GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture); GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
if(validationError != GL_NONE) if(validationError != GL_NONE)
{ {
return error(validationError); return error(validationError);
...@@ -6616,7 +6589,6 @@ void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint ...@@ -6616,7 +6589,6 @@ void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint
} }
GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize); GLenum validationError = context->getPixels(&data, texture->getType(target, level), imageSize);
if(validationError != GL_NONE) if(validationError != GL_NONE)
{ {
return error(validationError); return error(validationError);
......
...@@ -729,21 +729,19 @@ GL_APICALL void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xo ...@@ -729,21 +729,19 @@ GL_APICALL void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xo
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture); GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion());
if(validationError == GL_NONE) if(validationError != GL_NONE)
{ {
GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type)); return error(validationError);
if(validationError != GL_NONE)
{
return error(validationError);
}
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
} }
else
validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, sizedInternalFormat, type));
if(validationError != GL_NONE)
{ {
return error(validationError); return error(validationError);
} }
texture->subImage(context, level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), data);
} }
} }
...@@ -793,7 +791,7 @@ GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLin ...@@ -793,7 +791,7 @@ GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLin
GLenum colorbufferFormat = source->getFormat(); GLenum colorbufferFormat = source->getFormat();
es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray(); es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();
GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture); GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion());
if(validationError != GL_NONE) if(validationError != GL_NONE)
{ {
return error(validationError); return error(validationError);
...@@ -935,7 +933,7 @@ GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level ...@@ -935,7 +933,7 @@ GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
if(((width % 4) != 0) || ((height % 4) != 0) || if(((width % 4) != 0) || ((height % 4) != 0) ||
((xoffset % 4) != 0) || ((yoffset % 4) != 0)) ((xoffset % 4) != 0) || ((yoffset % 4) != 0))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
...@@ -967,7 +965,8 @@ GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level ...@@ -967,7 +965,8 @@ GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level
if(is_ETC2_EAC) if(is_ETC2_EAC)
{ {
if(((width + xoffset) != texture->getWidth(target, level)) || if(((width + xoffset) != texture->getWidth(target, level)) ||
((height + yoffset) != texture->getHeight(target, level))) ((height + yoffset) != texture->getHeight(target, level)) ||
((depth + zoffset) != texture->getDepth(target, level)))
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
...@@ -4085,7 +4084,7 @@ GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internal ...@@ -4085,7 +4084,7 @@ GL_APICALL void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internal
return; return;
} }
if(!IsColorRenderable(internalformat, egl::getClientVersion(), false) && if(!IsColorRenderable(internalformat, egl::getClientVersion()) &&
!IsDepthRenderable(internalformat, egl::getClientVersion()) && !IsDepthRenderable(internalformat, egl::getClientVersion()) &&
!IsStencilRenderable(internalformat, egl::getClientVersion())) !IsStencilRenderable(internalformat, egl::getClientVersion()))
{ {
......
...@@ -520,31 +520,40 @@ namespace es2 ...@@ -520,31 +520,40 @@ namespace es2
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
#if(ASTC_SUPPORT) #if(ASTC_SUPPORT)
return ((clientVersion >= 3) && ()) ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM; return ((clientVersion >= 3) && ()) ? (expectCompressedFormats ? GL_NONE : GL_INVALID_OPERATION) : GL_INVALID_ENUM;
#else #else
return GL_INVALID_ENUM; return GL_INVALID_ENUM;
#endif #endif
default: default:
return expectCompressedFormats ? GL_INVALID_ENUM : GL_NONE; // Not compressed format return expectCompressedFormats ? GL_INVALID_ENUM : GL_NONE; // Not compressed format
} }
} }
GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture) GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture, GLint clientVersion)
{ {
if(!texture) if(!texture)
{ {
return GL_INVALID_OPERATION; return GL_INVALID_OPERATION;
} }
if(compressed != texture->isCompressed(target, level)) GLenum sizedInternalFormat = texture->getFormat(target, level);
if(compressed)
{ {
return GL_INVALID_OPERATION; if(format != sizedInternalFormat)
{
return GL_INVALID_OPERATION;
}
} }
else if(!copy) // CopyTexSubImage doesn't have format/type parameters.
if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))
{ {
return GL_INVALID_OPERATION; GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, clientVersion);
if(validationError != GL_NONE)
{
return validationError;
}
} }
if(compressed) if(compressed)
...@@ -565,7 +574,8 @@ namespace es2 ...@@ -565,7 +574,8 @@ namespace es2
return GL_NONE; return GL_NONE;
} }
GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture) GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture, GLint clientVersion)
{ {
if(!texture) if(!texture)
{ {
...@@ -577,9 +587,15 @@ namespace es2 ...@@ -577,9 +587,15 @@ namespace es2
return GL_INVALID_OPERATION; return GL_INVALID_OPERATION;
} }
if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level))) if(!copy)
{ {
return GL_INVALID_OPERATION; GLenum sizedInternalFormat = texture->getFormat(target, level);
GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, clientVersion);
if(validationError != GL_NONE)
{
return validationError;
}
} }
if(compressed) if(compressed)
...@@ -761,7 +777,7 @@ namespace es2 ...@@ -761,7 +777,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 internalformat, GLint clientVersion) GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion)
{ {
switch(type) switch(type)
{ {
...@@ -785,11 +801,11 @@ namespace es2 ...@@ -785,11 +801,11 @@ namespace es2
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
if(clientVersion < 3) if(clientVersion < 3)
{ {
return error(GL_INVALID_ENUM, false); return GL_INVALID_ENUM;
} }
break; break;
default: default:
return error(GL_INVALID_ENUM, false); return GL_INVALID_ENUM;
} }
switch(format) switch(format)
...@@ -811,22 +827,42 @@ namespace es2 ...@@ -811,22 +827,42 @@ namespace es2
case GL_RGBA_INTEGER: case GL_RGBA_INTEGER:
if(clientVersion < 3) if(clientVersion < 3)
{ {
return error(GL_INVALID_ENUM, false); return GL_INVALID_ENUM;
} }
break; break;
default: default:
return error(GL_INVALID_ENUM, false); return GL_INVALID_ENUM;
} }
if((GLenum)internalformat != format) if((GLenum)internalformat != format)
{ {
if(clientVersion < 3)
{
return error(GL_INVALID_OPERATION, false);
}
switch(internalformat) switch(internalformat)
{ {
// Unsized internal formats:
case GL_ALPHA:
case GL_RGB:
case GL_RGBA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
case GL_DEPTH_STENCIL: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES)
case GL_DEPTH_COMPONENT: // GL_OES_depth_texture
case GL_RED: // = GL_RED_EXT in GL_EXT_texture_rg
case GL_RG: // = GL_RG_EXT in GL_EXT_texture_rg
break;
case GL_RED_INTEGER:
case GL_RG_INTEGER:
case GL_RGB_INTEGER:
case GL_RGBA_INTEGER:
if(clientVersion < 3)
{
return GL_INVALID_ENUM;
}
break;
// Sized internal formats:
case GL_ALPHA8_EXT:
case GL_LUMINANCE8_ALPHA8_EXT:
case GL_LUMINANCE8_EXT:
case GL_R8: case GL_R8:
case GL_R8UI: case GL_R8UI:
case GL_R8I: case GL_R8I:
...@@ -885,7 +921,7 @@ namespace es2 ...@@ -885,7 +921,7 @@ namespace es2
case GL_RGB9_E5: case GL_RGB9_E5:
break; break;
default: default:
return error(GL_INVALID_ENUM, false); return GL_INVALID_ENUM;
} }
} }
...@@ -906,7 +942,7 @@ namespace es2 ...@@ -906,7 +942,7 @@ namespace es2
case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, 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_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F) case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_RGBA_INTEGER: case GL_RGBA_INTEGER:
...@@ -919,7 +955,7 @@ namespace es2 ...@@ -919,7 +955,7 @@ namespace es2
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI) case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I) case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I)
case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI) case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_RGB: case GL_RGB:
...@@ -933,7 +969,7 @@ namespace es2 ...@@ -933,7 +969,7 @@ namespace es2
case GL_UNSIGNED_INT_5_9_9_9_REV: VALIDATE_INTERNALFORMAT(GL_RGB9_E5) 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_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) case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_RGB_INTEGER: case GL_RGB_INTEGER:
...@@ -945,7 +981,7 @@ namespace es2 ...@@ -945,7 +981,7 @@ namespace es2
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I) case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI) case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I) case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_RG: case GL_RG:
...@@ -956,7 +992,7 @@ namespace es2 ...@@ -956,7 +992,7 @@ namespace es2
case GL_HALF_FLOAT_OES: break; case GL_HALF_FLOAT_OES: break;
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F) case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F) case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_RG_INTEGER: case GL_RG_INTEGER:
...@@ -968,7 +1004,7 @@ namespace es2 ...@@ -968,7 +1004,7 @@ namespace es2
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16I) case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RG32UI) case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RG32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_RG32I) case GL_INT: VALIDATE_INTERNALFORMAT(GL_RG32I)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_RED: case GL_RED:
...@@ -979,7 +1015,7 @@ namespace es2 ...@@ -979,7 +1015,7 @@ namespace es2
case GL_HALF_FLOAT_OES: break; case GL_HALF_FLOAT_OES: break;
case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_R16F) case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_R16F)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F) case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_RED_INTEGER: case GL_RED_INTEGER:
...@@ -991,7 +1027,7 @@ namespace es2 ...@@ -991,7 +1027,7 @@ namespace es2
case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I) case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI) case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI)
case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I) case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT:
...@@ -1000,7 +1036,7 @@ namespace es2 ...@@ -1000,7 +1036,7 @@ namespace es2
case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16) case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16)
case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16) case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16)
case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F) case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_DEPTH_STENCIL: case GL_DEPTH_STENCIL:
...@@ -1008,41 +1044,61 @@ namespace es2 ...@@ -1008,41 +1044,61 @@ namespace es2
{ {
case GL_UNSIGNED_INT_24_8: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8) 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) case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8)
default: return error(GL_INVALID_OPERATION, false); default: return GL_INVALID_OPERATION;
} }
break; break;
case GL_LUMINANCE_ALPHA: case GL_LUMINANCE_ALPHA:
switch(type)
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT)
case GL_HALF_FLOAT_OES:
case GL_FLOAT:
break;
default:
return GL_INVALID_OPERATION;
}
break;
case GL_LUMINANCE: case GL_LUMINANCE:
switch(type)
{
case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT)
case GL_HALF_FLOAT_OES:
case GL_FLOAT:
break;
default:
return GL_INVALID_OPERATION;
}
break;
case GL_ALPHA: case GL_ALPHA:
switch(type) switch(type)
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT)
case GL_HALF_FLOAT_OES: case GL_HALF_FLOAT_OES:
case GL_FLOAT: case GL_FLOAT:
break; break;
default: default:
return error(GL_INVALID_OPERATION, false); return GL_INVALID_OPERATION;
} }
break; break;
case GL_BGRA_EXT: case GL_BGRA_EXT:
if(type != GL_UNSIGNED_BYTE) if(type != GL_UNSIGNED_BYTE)
{ {
return error(GL_INVALID_OPERATION, false); return GL_INVALID_OPERATION;
} }
break; break;
default: default:
UNREACHABLE(format); UNREACHABLE(format);
return error(GL_INVALID_ENUM, false); return GL_INVALID_ENUM;
} }
#undef VALIDATE_INTERNALFORMAT #undef VALIDATE_INTERNALFORMAT
if((GLenum)internalformat != format && !validSizedInternalformat) if((GLenum)internalformat != format && !validSizedInternalformat)
{ {
return error(GL_INVALID_OPERATION, false); return GL_INVALID_OPERATION;
} }
return true; return GL_NONE;
} }
GLsizei GetTypeSize(GLenum type) GLsizei GetTypeSize(GLenum type)
...@@ -1077,22 +1133,17 @@ namespace es2 ...@@ -1077,22 +1133,17 @@ namespace es2
return 1; return 1;
} }
bool IsColorRenderable(GLenum internalformat, GLint clientVersion, bool isTexture) bool IsColorRenderable(GLint internalformat, GLint clientVersion)
{ {
switch(internalformat) switch(internalformat)
{ {
case GL_RED_EXT:
case GL_RG_EXT:
case GL_RGB:
case GL_RGBA:
return isTexture;
case GL_RGBA4: case GL_RGBA4:
case GL_RGB5_A1: case GL_RGB5_A1:
case GL_RGB565: case GL_RGB565:
case GL_R8_EXT: case GL_R8:
case GL_RG8_EXT: case GL_RG8:
case GL_RGB8_OES: case GL_RGB8:
case GL_RGBA8_OES: case GL_RGBA8:
case GL_R16F: case GL_R16F:
case GL_RG16F: case GL_RG16F:
case GL_RGB16F: case GL_RGB16F:
...@@ -1148,25 +1199,7 @@ namespace es2 ...@@ -1148,25 +1199,7 @@ namespace es2
return false; return false;
} }
bool IsMipmappable(GLenum internalformat, sw::Format internalFormat, GLint clientVersion) bool IsDepthRenderable(GLint internalformat, GLint clientVersion)
{
if(sw::Surface::isNonNormalizedInteger(internalFormat))
{
return false;
}
switch(internalformat)
{
case GL_ALPHA8_EXT:
case GL_LUMINANCE8_EXT:
case GL_LUMINANCE8_ALPHA8_EXT:
return true;
default:
return IsColorRenderable(internalformat, clientVersion, true);
}
}
bool IsDepthRenderable(GLenum internalformat, GLint clientVersion)
{ {
switch(internalformat) switch(internalformat)
{ {
...@@ -1220,6 +1253,10 @@ namespace es2 ...@@ -1220,6 +1253,10 @@ namespace es2
case GL_RG32F: case GL_RG32F:
case GL_RGB32F: case GL_RGB32F:
case GL_RGBA32F: case GL_RGBA32F:
case GL_R8_SNORM:
case GL_RG8_SNORM:
case GL_RGB8_SNORM:
case GL_RGBA8_SNORM:
return false; return false;
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
...@@ -1228,7 +1265,7 @@ namespace es2 ...@@ -1228,7 +1265,7 @@ namespace es2
return false; return false;
} }
bool IsStencilRenderable(GLenum internalformat, GLint clientVersion) bool IsStencilRenderable(GLint internalformat, GLint clientVersion)
{ {
switch(internalformat) switch(internalformat)
{ {
...@@ -1282,6 +1319,10 @@ namespace es2 ...@@ -1282,6 +1319,10 @@ namespace es2
case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32_OES: case GL_DEPTH_COMPONENT32_OES:
case GL_DEPTH_COMPONENT32F: case GL_DEPTH_COMPONENT32F:
case GL_R8_SNORM:
case GL_RG8_SNORM:
case GL_RGB8_SNORM:
case GL_RGBA8_SNORM:
return false; return false;
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
...@@ -1290,6 +1331,24 @@ namespace es2 ...@@ -1290,6 +1331,24 @@ namespace es2
return false; return false;
} }
bool IsMipmappable(GLint internalformat, sw::Format format, GLint clientVersion)
{
if(sw::Surface::isNonNormalizedInteger(format))
{
return false;
}
switch(internalformat)
{
case GL_ALPHA8_EXT:
case GL_LUMINANCE8_EXT:
case GL_LUMINANCE8_ALPHA8_EXT:
return true;
default:
return IsColorRenderable(internalformat, clientVersion);
}
}
std::string ParseUniformName(const std::string &name, unsigned int *outSubscript) std::string ParseUniformName(const std::string &name, unsigned int *outSubscript)
{ {
// Strip any trailing array operator and retrieve the subscript // Strip any trailing array operator and retrieve the subscript
......
...@@ -45,21 +45,23 @@ namespace es2 ...@@ -45,21 +45,23 @@ namespace es2
bool IsCompressed(GLenum format, GLint clientVersion); bool IsCompressed(GLenum format, GLint clientVersion);
GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type); GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats); GLenum ValidateCompressedFormat(GLenum format, GLint clientVersion, bool expectCompressedFormats);
GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture); GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture); GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture, GLint clientVersion);
GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture, GLint clientVersion);
bool IsValidReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type, GLint clientVersion); bool IsValidReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type, GLint clientVersion);
bool IsDepthTexture(GLenum format); bool IsDepthTexture(GLenum format);
bool IsStencilTexture(GLenum format); bool IsStencilTexture(GLenum format);
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 internalformat, GLint clientVersion); GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLint clientVersion);
GLsizei GetTypeSize(GLenum type); GLsizei GetTypeSize(GLenum type);
bool IsColorRenderable(GLenum internalformat, GLint clientVersion, bool isTexture); bool IsColorRenderable(GLint internalformat, GLint clientVersion);
bool IsMipmappable(GLenum format, sw::Format internalFormat, GLint clientVersion); bool IsDepthRenderable(GLint internalformat, GLint clientVersion);
bool IsDepthRenderable(GLenum internalformat, GLint clientVersion); bool IsStencilRenderable(GLint internalformat, GLint clientVersion);
bool IsStencilRenderable(GLenum internalformat, GLint clientVersion); bool IsMipmappable(GLint internalformat, sw::Format format, GLint clientVersion);
// Parse the base uniform name and array index. Returns the base name of the uniform. outSubscript is // Parse the base uniform name and array index. Returns the base name of the uniform. outSubscript is
// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid. // set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid.
......
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