Refactor common attachment validation to base method.
Split the validation of FBO attachment binding to common methods
and separate logic for layers and for 2D attachments.
BUG=angle:571
Change-Id: I9a59055cca60dd853311751be355440ad1e5ead0
Reviewed-on: https://chromium-review.googlesource.com/205605
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index b1c4810..d940b9e 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -1446,21 +1446,112 @@
return (primcount > 0);
}
-bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
+bool ValidateFramebufferTextureBase(const gl::Context *context, GLenum target, GLenum attachment,
+ GLuint texture, GLint level)
{
- if (context->getClientVersion() < 3 &&
- !ValidateES2FramebufferTextureParameters(context, target, attachment, textarget, texture, level))
+ if (!ValidFramebufferTarget(target))
+ {
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ if (!ValidateAttachmentTarget(context, attachment))
{
return false;
}
- if (context->getClientVersion() >= 3 &&
- !ValidateES3FramebufferTextureParameters(context, target, attachment, textarget, texture, level, 0, false))
+ if (texture != 0)
+ {
+ gl::Texture *tex = context->getTexture(texture);
+
+ if (tex == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
+ if (level < 0)
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+ }
+
+ const gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target);
+ GLuint framebufferHandle = context->getTargetFramebufferHandle(target);
+
+ if (framebufferHandle == 0 || !framebuffer)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTexture2D(const gl::Context *context, GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ // Attachments are required to be bound to level 0 in ES2
+ if (context->getClientVersion() < 3 && level != 0)
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+
+ if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
{
return false;
}
+ if (texture != 0)
+ {
+ gl::Texture *tex = context->getTexture(texture);
+ ASSERT(tex);
+
+ switch (textarget)
+ {
+ case GL_TEXTURE_2D:
+ {
+ if (level > gl::log2(context->getMaximum2DTextureDimension()))
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+ if (tex->getTarget() != GL_TEXTURE_2D)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
+ if (tex2d->isCompressed(level))
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ }
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ {
+ if (level > gl::log2(context->getMaximumCubeTextureDimension()))
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+ if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
+ if (texcube->isCompressed(textarget, level))
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+ }
+ break;
+
+ default:
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+ }
+
return true;
}