Refactored glRenderBufferStorage* validation and implemented glRenderBufferStorageMultisample.
TRAC #23212
Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 434514f..4b83f9f 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -1454,6 +1454,82 @@
return true;
}
+bool validateRenderbufferStorageParameters(const gl::Context *context, GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height,
+ bool angleExtension)
+{
+ switch (target)
+ {
+ case GL_RENDERBUFFER:
+ break;
+ default:
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ if (width < 0 || height < 0 || samples < 0)
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+
+ if (!gl::IsValidInternalFormat(internalformat, context))
+ {
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
+ // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
+ // only sized internal formats. The ES3 spec (section 4.4.2) does, however, state that the
+ // internal format must be sized and not an integer format if samples is greater than zero.
+ if (!gl::IsSizedInternalFormat(internalformat, context->getClientVersion()))
+ {
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ if (gl::IsIntegerFormat(internalformat, context->getClientVersion()) && samples > 0)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
+ if (!gl::IsColorRenderingSupported(internalformat, context) &&
+ !gl::IsDepthRenderingSupported(internalformat, context) &&
+ !gl::IsStencilRenderingSupported(internalformat, context))
+ {
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ if (std::max(width, height) > context->getMaximumRenderbufferDimension())
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+
+ // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
+ // to MAX_SAMPLES_ANGLE (Context::getMaxSupportedSamples) while the ES3.0 spec (section 4.4.2)
+ // states that samples must be less than or equal to the maximum samples for the specified
+ // internal format.
+ if (angleExtension)
+ {
+ if (samples > context->getMaxSupportedSamples())
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+ }
+ else
+ {
+ if (samples > context->getMaxSupportedFormatSamples(internalformat))
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+ }
+
+ GLuint handle = context->getRenderbufferHandle();
+ if (handle == 0)
+ {
+ return gl::error(GL_INVALID_OPERATION, false);
+ }
+
+ return true;
+}
+
// check for combinations of format and type that are valid for ReadPixels
bool validES2ReadFormatType(GLenum format, GLenum type)
{
@@ -6168,70 +6244,14 @@
try
{
- switch (target)
- {
- case GL_RENDERBUFFER:
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
- }
-
- if (width < 0 || height < 0 || samples < 0)
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
gl::Context *context = gl::getNonLostContext();
if (context)
{
- if (!gl::IsValidInternalFormat(internalformat, context))
+ if (!validateRenderbufferStorageParameters(context, target, samples, internalformat,
+ width, height, true))
{
- return gl::error(GL_INVALID_ENUM);
- }
-
- if (!gl::IsColorRenderingSupported(internalformat, context) &&
- !gl::IsDepthRenderingSupported(internalformat, context) &&
- !gl::IsStencilRenderingSupported(internalformat, context))
- {
- return gl::error(GL_INVALID_ENUM);
- }
-
- if (width > context->getMaximumRenderbufferDimension() ||
- height > context->getMaximumRenderbufferDimension() ||
- samples > context->getMaxSupportedSamples())
- {
- return gl::error(GL_INVALID_VALUE);
- }
-
- GLuint handle = context->getRenderbufferHandle();
- if (handle == 0)
- {
- return gl::error(GL_INVALID_OPERATION);
- }
-
- switch (internalformat)
- {
- case GL_DEPTH_COMPONENT16:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGB565:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
- case GL_STENCIL_INDEX8:
- case GL_DEPTH24_STENCIL8_OES:
- break;
- case GL_SRGB8_ALPHA8:
- case GL_RGB10_A2:
- case GL_RG8:
- case GL_R8:
- if (context->getClientVersion() < 3)
- {
- return gl::error(GL_INVALID_ENUM);
- }
- break;
- default:
- return gl::error(GL_INVALID_ENUM);
+ return;
}
context->setRenderbufferStorage(width, height, internalformat, samples);
@@ -8770,7 +8790,13 @@
return gl::error(GL_INVALID_OPERATION);
}
- glRenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
+ if (!validateRenderbufferStorageParameters(context, target, samples, internalformat,
+ width, height, false))
+ {
+ return;
+ }
+
+ context->setRenderbufferStorage(width, height, internalformat, samples);
}
}
catch(std::bad_alloc&)