summaryrefslogtreecommitdiff
path: root/gfx/angle/src/libANGLE/validationES.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/validationES.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/validationES.cpp2973
1 files changed, 393 insertions, 2580 deletions
diff --git a/gfx/angle/src/libANGLE/validationES.cpp b/gfx/angle/src/libANGLE/validationES.cpp
index 79e3f66365..1bbfe866e1 100755
--- a/gfx/angle/src/libANGLE/validationES.cpp
+++ b/gfx/angle/src/libANGLE/validationES.cpp
@@ -99,1190 +99,41 @@ bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxV
return true;
}
-bool ValidReadPixelsFormatType(ValidationContext *context,
- GLenum framebufferComponentType,
- GLenum format,
- GLenum type)
-{
- switch (framebufferComponentType)
- {
- case GL_UNSIGNED_NORMALIZED:
- // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
- // ReadPixels with BGRA even if the extension is not present
- return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
- (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
- type == GL_UNSIGNED_BYTE);
-
- case GL_SIGNED_NORMALIZED:
- return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
-
- case GL_INT:
- return (format == GL_RGBA_INTEGER && type == GL_INT);
-
- case GL_UNSIGNED_INT:
- return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
-
- case GL_FLOAT:
- return (format == GL_RGBA && type == GL_FLOAT);
-
- default:
- UNREACHABLE();
- return false;
- }
-}
+} // anonymous namespace
-bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
+bool ValidCap(const Context *context, GLenum cap)
{
switch (cap)
{
- // EXT_multisample_compatibility
- case GL_MULTISAMPLE_EXT:
- case GL_SAMPLE_ALPHA_TO_ONE_EXT:
- return context->getExtensions().multisampleCompatibility;
-
- case GL_CULL_FACE:
- case GL_POLYGON_OFFSET_FILL:
- case GL_SAMPLE_ALPHA_TO_COVERAGE:
- case GL_SAMPLE_COVERAGE:
- case GL_SCISSOR_TEST:
- case GL_STENCIL_TEST:
- case GL_DEPTH_TEST:
- case GL_BLEND:
- case GL_DITHER:
- return true;
-
- case GL_PRIMITIVE_RESTART_FIXED_INDEX:
- case GL_RASTERIZER_DISCARD:
- return (context->getClientMajorVersion() >= 3);
-
- case GL_DEBUG_OUTPUT_SYNCHRONOUS:
- case GL_DEBUG_OUTPUT:
- return context->getExtensions().debug;
-
- case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
- return queryOnly && context->getExtensions().bindGeneratesResource;
-
- case GL_FRAMEBUFFER_SRGB_EXT:
- return context->getExtensions().sRGBWriteControl;
-
- default:
- return false;
- }
-}
-
-bool ValidateReadPixelsBase(ValidationContext *context,
- GLint x,
- GLint y,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- GLsizei bufSize,
- GLsizei *length,
- GLvoid *pixels)
-{
- if (length != nullptr)
- {
- *length = 0;
- }
-
- if (width < 0 || height < 0)
- {
- context->handleError(Error(GL_INVALID_VALUE, "width and height must be positive"));
- return false;
- }
-
- auto readFramebuffer = context->getGLState().getReadFramebuffer();
-
- if (readFramebuffer->checkStatus(context->getContextState()) != GL_FRAMEBUFFER_COMPLETE)
- {
- context->handleError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
- return false;
- }
-
- if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context->getContextState()) != 0)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
- ASSERT(framebuffer);
-
- if (framebuffer->getReadBufferState() == GL_NONE)
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Read buffer is GL_NONE"));
- return false;
- }
-
- const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
- if (!readBuffer)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- GLenum currentFormat = framebuffer->getImplementationColorReadFormat();
- GLenum currentType = framebuffer->getImplementationColorReadType();
- GLenum currentInternalFormat = readBuffer->getFormat().asSized();
-
- const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(currentInternalFormat);
- bool validFormatTypeCombination =
- ValidReadPixelsFormatType(context, internalFormatInfo.componentType, format, type);
-
- if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- // Check for pixel pack buffer related API errors
- gl::Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER);
- if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
- {
- // ...the buffer object's data store is currently mapped.
- context->handleError(Error(GL_INVALID_OPERATION, "Pixel pack buffer is mapped."));
- return false;
- }
-
- // .. the data would be packed to the buffer object such that the memory writes required
- // would exceed the data store size.
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
- const InternalFormat &formatInfo = GetInternalFormatInfo(sizedInternalFormat);
- const gl::Extents size(width, height, 1);
- const auto &pack = context->getGLState().getPackState();
-
- auto endByteOrErr = formatInfo.computePackUnpackEndByte(size, pack, false);
- if (endByteOrErr.isError())
- {
- context->handleError(endByteOrErr.getError());
- return false;
- }
-
- size_t endByte = endByteOrErr.getResult();
- if (bufSize >= 0)
- {
-
- if (static_cast<size_t>(bufSize) < endByte)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "bufSize must be at least %u bytes.", endByte));
- return false;
- }
- }
-
- if (pixelPackBuffer != nullptr)
- {
- CheckedNumeric<size_t> checkedEndByte(endByte);
- CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
- checkedEndByte += checkedOffset;
-
- if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
- {
- // Overflow past the end of the buffer
- context->handleError(
- Error(GL_INVALID_OPERATION, "Writes would overflow the pixel pack buffer."));
- return false;
- }
- }
-
- if (length != nullptr)
- {
- if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "length would overflow GLsizei.", endByte));
- return false;
- }
-
- *length = static_cast<GLsizei>(endByte);
- }
-
- return true;
-}
-
-bool ValidateGetRenderbufferParameterivBase(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei *length)
-{
- if (length)
- {
- *length = 0;
- }
-
- if (target != GL_RENDERBUFFER)
- {
- context->handleError(Error(GL_INVALID_ENUM, "Invalid target."));
- return false;
- }
-
- Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
- if (renderbuffer == nullptr)
- {
- context->handleError(Error(GL_INVALID_OPERATION, "No renderbuffer bound."));
- return false;
- }
-
- switch (pname)
- {
- case GL_RENDERBUFFER_WIDTH:
- case GL_RENDERBUFFER_HEIGHT:
- case GL_RENDERBUFFER_INTERNAL_FORMAT:
- case GL_RENDERBUFFER_RED_SIZE:
- case GL_RENDERBUFFER_GREEN_SIZE:
- case GL_RENDERBUFFER_BLUE_SIZE:
- case GL_RENDERBUFFER_ALPHA_SIZE:
- case GL_RENDERBUFFER_DEPTH_SIZE:
- case GL_RENDERBUFFER_STENCIL_SIZE:
- break;
-
- case GL_RENDERBUFFER_SAMPLES_ANGLE:
- if (!context->getExtensions().framebufferMultisample)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_ANGLE_framebuffer_multisample is not enabled."));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- if (length)
- {
- *length = 1;
- }
- return true;
-}
-
-bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
-{
- if (length)
- {
- *length = 0;
- }
-
- if (GetValidShader(context, shader) == nullptr)
- {
- return false;
- }
-
- switch (pname)
- {
- case GL_SHADER_TYPE:
- case GL_DELETE_STATUS:
- case GL_COMPILE_STATUS:
- case GL_INFO_LOG_LENGTH:
- case GL_SHADER_SOURCE_LENGTH:
- break;
-
- case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
- if (!context->getExtensions().translatedShaderSource)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_ANGLE_translated_shader_source is not enabled."));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- if (length)
- {
- *length = 1;
- }
- return true;
-}
-
-bool ValidateGetTexParameterBase(Context *context, GLenum target, GLenum pname, GLsizei *length)
-{
- if (length)
- {
- *length = 0;
- }
-
- if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
- {
- context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
- return false;
- }
-
- if (context->getTargetTexture(target) == nullptr)
- {
- // Should only be possible for external textures
- context->handleError(Error(GL_INVALID_ENUM, "No texture bound."));
- return false;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_MAG_FILTER:
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- break;
-
- case GL_TEXTURE_USAGE_ANGLE:
- if (!context->getExtensions().textureUsage)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_ANGLE_texture_usage is not enabled."));
- return false;
- }
- break;
-
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (!context->getExtensions().textureFilterAnisotropic)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_EXT_texture_filter_anisotropic is not enabled."));
- return false;
- }
- break;
-
- case GL_TEXTURE_IMMUTABLE_FORMAT:
- if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_EXT_texture_storage is not enabled."));
- return false;
- }
- break;
-
- case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_IMMUTABLE_LEVELS:
- case GL_TEXTURE_SWIZZLE_R:
- case GL_TEXTURE_SWIZZLE_G:
- case GL_TEXTURE_SWIZZLE_B:
- case GL_TEXTURE_SWIZZLE_A:
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- case GL_TEXTURE_COMPARE_MODE:
- case GL_TEXTURE_COMPARE_FUNC:
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0."));
- return false;
- }
- break;
-
- case GL_TEXTURE_SRGB_DECODE_EXT:
- if (!context->getExtensions().textureSRGBDecode)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_EXT_texture_sRGB_decode is not enabled."));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- if (length)
- {
- *length = 1;
- }
- return true;
-}
-
-template <typename ParamType>
-bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool isExternalTextureTarget)
-{
- switch (ConvertToGLenum(params[0]))
- {
- case GL_CLAMP_TO_EDGE:
- break;
-
- case GL_REPEAT:
- case GL_MIRRORED_REPEAT:
- if (isExternalTextureTarget)
- {
- // OES_EGL_image_external specifies this error.
- context->handleError(Error(
- GL_INVALID_ENUM, "external textures only support CLAMP_TO_EDGE wrap mode"));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
-
- return true;
-}
-
-template <typename ParamType>
-bool ValidateTextureMinFilterValue(Context *context,
- ParamType *params,
- bool isExternalTextureTarget)
-{
- switch (ConvertToGLenum(params[0]))
- {
- case GL_NEAREST:
- case GL_LINEAR:
- break;
-
- case GL_NEAREST_MIPMAP_NEAREST:
- case GL_LINEAR_MIPMAP_NEAREST:
- case GL_NEAREST_MIPMAP_LINEAR:
- case GL_LINEAR_MIPMAP_LINEAR:
- if (isExternalTextureTarget)
- {
- // OES_EGL_image_external specifies this error.
- context->handleError(
- Error(GL_INVALID_ENUM,
- "external textures only support NEAREST and LINEAR filtering"));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
-
- return true;
-}
-
-template <typename ParamType>
-bool ValidateTextureMagFilterValue(Context *context, ParamType *params)
-{
- switch (ConvertToGLenum(params[0]))
- {
- case GL_NEAREST:
- case GL_LINEAR:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
-
- return true;
-}
-
-template <typename ParamType>
-bool ValidateTextureCompareModeValue(Context *context, ParamType *params)
-{
- // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
- switch (ConvertToGLenum(params[0]))
- {
- case GL_NONE:
- case GL_COMPARE_REF_TO_TEXTURE:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
-
- return true;
-}
-
-template <typename ParamType>
-bool ValidateTextureCompareFuncValue(Context *context, ParamType *params)
-{
- // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
- switch (ConvertToGLenum(params[0]))
- {
- case GL_LEQUAL:
- case GL_GEQUAL:
- case GL_LESS:
- case GL_GREATER:
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_ALWAYS:
- case GL_NEVER:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
-
- return true;
-}
-
-template <typename ParamType>
-bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params)
-{
- if (!context->getExtensions().textureSRGBDecode)
- {
- context->handleError(Error(GL_INVALID_ENUM, "GL_EXT_texture_sRGB_decode is not enabled."));
- return false;
- }
-
- switch (ConvertToGLenum(params[0]))
- {
- case GL_DECODE_EXT:
- case GL_SKIP_DECODE_EXT:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
-
- return true;
-}
-
-template <typename ParamType>
-bool ValidateTexParameterBase(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- ParamType *params)
-{
- if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
- {
- context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
- return false;
- }
-
- if (context->getTargetTexture(target) == nullptr)
- {
- // Should only be possible for external textures
- context->handleError(Error(GL_INVALID_ENUM, "No texture bound."));
- return false;
- }
-
- const GLsizei minBufSize = 1;
- if (bufSize >= 0 && bufSize < minBufSize)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "bufSize must be at least %i.", minBufSize));
- return false;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_SWIZZLE_R:
- case GL_TEXTURE_SWIZZLE_G:
- case GL_TEXTURE_SWIZZLE_B:
- case GL_TEXTURE_SWIZZLE_A:
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- case GL_TEXTURE_COMPARE_MODE:
- case GL_TEXTURE_COMPARE_FUNC:
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0."));
- return false;
- }
- if (target == GL_TEXTURE_EXTERNAL_OES &&
- !context->getExtensions().eglImageExternalEssl3)
- {
- context->handleError(Error(GL_INVALID_ENUM,
- "ES3 texture parameters are not available without "
- "GL_OES_EGL_image_external_essl3."));
- return false;
- }
- break;
-
- default:
- break;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- case GL_TEXTURE_WRAP_R:
- if (!ValidateTextureWrapModeValue(context, params, target == GL_TEXTURE_EXTERNAL_OES))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_MIN_FILTER:
- if (!ValidateTextureMinFilterValue(context, params, target == GL_TEXTURE_EXTERNAL_OES))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_MAG_FILTER:
- if (!ValidateTextureMagFilterValue(context, params))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_USAGE_ANGLE:
- switch (ConvertToGLenum(params[0]))
- {
- case GL_NONE:
- case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
- break;
-
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (!context->getExtensions().textureFilterAnisotropic)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_EXT_texture_anisotropic is not enabled."));
- return false;
- }
-
- // we assume the parameter passed to this validation method is truncated, not rounded
- if (params[0] < 1)
- {
- context->handleError(Error(GL_INVALID_VALUE, "Max anisotropy must be at least 1."));
- return false;
- }
- break;
-
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- // any value is permissible
- break;
-
- case GL_TEXTURE_COMPARE_MODE:
- if (!ValidateTextureCompareModeValue(context, params))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_COMPARE_FUNC:
- if (!ValidateTextureCompareFuncValue(context, params))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_SWIZZLE_R:
- case GL_TEXTURE_SWIZZLE_G:
- case GL_TEXTURE_SWIZZLE_B:
- case GL_TEXTURE_SWIZZLE_A:
- switch (ConvertToGLenum(params[0]))
- {
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_ZERO:
- case GL_ONE:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown param value."));
- return false;
- }
- break;
-
- case GL_TEXTURE_BASE_LEVEL:
- if (params[0] < 0)
- {
- context->handleError(Error(GL_INVALID_VALUE, "Base level must be at least 0."));
- return false;
- }
- if (target == GL_TEXTURE_EXTERNAL_OES && static_cast<GLuint>(params[0]) != 0)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "Base level must be 0 for external textures."));
- return false;
- }
- break;
-
- case GL_TEXTURE_MAX_LEVEL:
- if (params[0] < 0)
- {
- context->handleError(Error(GL_INVALID_VALUE, "Max level must be at least 0."));
- return false;
- }
- break;
-
- case GL_TEXTURE_SRGB_DECODE_EXT:
- if (!ValidateTextureSRGBDecodeValue(context, params))
- {
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- return true;
-}
-
-template <typename ParamType>
-bool ValidateSamplerParameterBase(Context *context,
- GLuint sampler,
- GLenum pname,
- GLsizei bufSize,
- ParamType *params)
-{
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0."));
- return false;
- }
-
- if (!context->isSampler(sampler))
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Sampler is not valid."));
- return false;
- }
-
- const GLsizei minBufSize = 1;
- if (bufSize >= 0 && bufSize < minBufSize)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "bufSize must be at least %i.", minBufSize));
- return false;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- case GL_TEXTURE_WRAP_R:
- if (!ValidateTextureWrapModeValue(context, params, false))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_MIN_FILTER:
- if (!ValidateTextureMinFilterValue(context, params, false))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_MAG_FILTER:
- if (!ValidateTextureMagFilterValue(context, params))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- // any value is permissible
- break;
-
- case GL_TEXTURE_COMPARE_MODE:
- if (!ValidateTextureCompareModeValue(context, params))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_COMPARE_FUNC:
- if (!ValidateTextureCompareFuncValue(context, params))
- {
- return false;
- }
- break;
-
- case GL_TEXTURE_SRGB_DECODE_EXT:
- if (!ValidateTextureSRGBDecodeValue(context, params))
- {
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetSamplerParameterBase(Context *context,
- GLuint sampler,
- GLenum pname,
- GLsizei *length)
-{
- if (length)
- {
- *length = 0;
- }
-
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0."));
- return false;
- }
-
- if (!context->isSampler(sampler))
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Sampler is not valid."));
- return false;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_MAG_FILTER:
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- case GL_TEXTURE_COMPARE_MODE:
- case GL_TEXTURE_COMPARE_FUNC:
- break;
-
- case GL_TEXTURE_SRGB_DECODE_EXT:
- if (!context->getExtensions().textureSRGBDecode)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "GL_EXT_texture_sRGB_decode is not enabled."));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- if (length)
- {
- *length = 1;
- }
- return true;
-}
-
-bool ValidateGetVertexAttribBase(Context *context,
- GLuint index,
- GLenum pname,
- GLsizei *length,
- bool pointer,
- bool pureIntegerEntryPoint)
-{
- if (length)
- {
- *length = 0;
- }
-
- if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0."));
- return false;
- }
-
- if (index >= context->getCaps().maxVertexAttributes)
- {
- context->handleError(Error(
- GL_INVALID_VALUE, "index must be less than the value of GL_MAX_VERTEX_ATTRIBUTES."));
- return false;
- }
-
- if (pointer)
- {
- if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
- {
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
- }
- else
- {
- switch (pname)
- {
- case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
- case GL_VERTEX_ATTRIB_ARRAY_SIZE:
- case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
- case GL_VERTEX_ATTRIB_ARRAY_TYPE:
- case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
- case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- case GL_CURRENT_VERTEX_ATTRIB:
- break;
-
- case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
- static_assert(
- GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
- "ANGLE extension enums not equal to GL enums.");
- if (context->getClientMajorVersion() < 3 &&
- !context->getExtensions().instancedArrays)
- {
- context->handleError(Error(GL_INVALID_ENUM,
- "GL_VERTEX_ATTRIB_ARRAY_DIVISOR requires OpenGL ES "
- "3.0 or GL_ANGLE_instanced_arrays."));
- return false;
- }
- break;
-
- case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0."));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
- }
-
- if (length)
- {
- if (pname == GL_CURRENT_VERTEX_ATTRIB)
- {
- *length = 4;
- }
- else
- {
- *length = 1;
- }
- }
-
- return true;
-}
-
-bool ValidateGetActiveUniformBlockivBase(Context *context,
- GLuint program,
- GLuint uniformBlockIndex,
- GLenum pname,
- GLsizei *length)
-{
- if (length)
- {
- *length = 0;
- }
-
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0."));
- return false;
- }
-
- Program *programObject = GetValidProgram(context, program);
- if (!programObject)
- {
- return false;
- }
-
- if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
- {
- context->handleError(
- Error(GL_INVALID_VALUE, "uniformBlockIndex exceeds active uniform block count."));
- return false;
- }
-
- switch (pname)
- {
- case GL_UNIFORM_BLOCK_BINDING:
- case GL_UNIFORM_BLOCK_DATA_SIZE:
- case GL_UNIFORM_BLOCK_NAME_LENGTH:
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
- case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
- case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- if (length)
- {
- if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
- {
- const UniformBlock &uniformBlock =
- programObject->getUniformBlockByIndex(uniformBlockIndex);
- *length = static_cast<GLsizei>(uniformBlock.memberUniformIndexes.size());
- }
- else
- {
- *length = 1;
- }
- }
-
- return true;
-}
-
-bool ValidateGetBufferParameterBase(ValidationContext *context,
- GLenum target,
- GLenum pname,
- bool pointerVersion,
- GLsizei *numParams)
-{
- if (numParams)
- {
- *numParams = 0;
- }
-
- if (!ValidBufferTarget(context, target))
- {
- context->handleError(Error(GL_INVALID_ENUM, "Invalid buffer target."));
- return false;
- }
-
- const Buffer *buffer = context->getGLState().getTargetBuffer(target);
- if (!buffer)
- {
- // A null buffer means that "0" is bound to the requested buffer target
- context->handleError(Error(GL_INVALID_OPERATION, "No buffer bound."));
- return false;
- }
-
- const Extensions &extensions = context->getExtensions();
-
- switch (pname)
- {
- case GL_BUFFER_USAGE:
- case GL_BUFFER_SIZE:
- break;
-
- case GL_BUFFER_ACCESS_OES:
- if (!extensions.mapBuffer)
- {
- context->handleError(
- Error(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_OES_map_buffer."));
- return false;
- }
- break;
-
- case GL_BUFFER_MAPPED:
- static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
- if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
- !extensions.mapBufferRange)
- {
- context->handleError(Error(
- GL_INVALID_ENUM,
- "pname requires OpenGL ES 3.0, GL_OES_map_buffer or GL_EXT_map_buffer_range."));
- return false;
- }
- break;
-
- case GL_BUFFER_MAP_POINTER:
- if (!pointerVersion)
- {
- context->handleError(
- Error(GL_INVALID_ENUM,
- "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv."));
- return false;
- }
- break;
-
- case GL_BUFFER_ACCESS_FLAGS:
- case GL_BUFFER_MAP_OFFSET:
- case GL_BUFFER_MAP_LENGTH:
- if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
- {
- context->handleError(Error(
- GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range."));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- // All buffer parameter queries return one value.
- if (numParams)
- {
- *numParams = 1;
- }
-
- return true;
-}
-
-bool ValidateGetInternalFormativBase(Context *context,
- GLenum target,
- GLenum internalformat,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *numParams)
-{
- if (numParams)
- {
- *numParams = 0;
- }
-
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0."));
- return false;
- }
-
- const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
- if (!formatCaps.renderable)
- {
- context->handleError(Error(GL_INVALID_ENUM, "Internal format is not renderable."));
- return false;
- }
+ // EXT_multisample_compatibility
+ case GL_MULTISAMPLE_EXT:
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ return context->getExtensions().multisampleCompatibility;
+
+ case GL_CULL_FACE:
+ case GL_POLYGON_OFFSET_FILL:
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ case GL_SAMPLE_COVERAGE:
+ case GL_SCISSOR_TEST:
+ case GL_STENCIL_TEST:
+ case GL_DEPTH_TEST:
+ case GL_BLEND:
+ case GL_DITHER:
+ return true;
- switch (target)
- {
- case GL_RENDERBUFFER:
- break;
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+ case GL_RASTERIZER_DISCARD:
+ return (context->getClientMajorVersion() >= 3);
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Invalid target."));
- return false;
- }
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+ case GL_DEBUG_OUTPUT:
+ return context->getExtensions().debug;
- if (bufSize < 0)
- {
- context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
+ default:
return false;
}
-
- GLsizei maxWriteParams = 0;
- switch (pname)
- {
- case GL_NUM_SAMPLE_COUNTS:
- maxWriteParams = 1;
- break;
-
- case GL_SAMPLES:
- maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
- }
-
- if (numParams)
- {
- // glGetInternalFormativ will not overflow bufSize
- *numParams = std::min(bufSize, maxWriteParams);
- }
-
- return true;
}
-} // anonymous namespace
-
bool ValidTextureTarget(const ValidationContext *context, GLenum target)
{
switch (target)
@@ -1382,7 +233,7 @@ bool ValidFramebufferTarget(GLenum target)
}
}
-bool ValidBufferTarget(const ValidationContext *context, GLenum target)
+bool ValidBufferTarget(const Context *context, GLenum target)
{
switch (target)
{
@@ -1406,6 +257,36 @@ bool ValidBufferTarget(const ValidationContext *context, GLenum target)
}
}
+bool ValidBufferParameter(const Context *context, GLenum pname)
+{
+ const Extensions &extensions = context->getExtensions();
+
+ switch (pname)
+ {
+ case GL_BUFFER_USAGE:
+ case GL_BUFFER_SIZE:
+ return true;
+
+ case GL_BUFFER_ACCESS_OES:
+ return extensions.mapBuffer;
+
+ case GL_BUFFER_MAPPED:
+ static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
+ return (context->getClientMajorVersion() >= 3) || extensions.mapBuffer ||
+ extensions.mapBufferRange;
+
+ // GL_BUFFER_MAP_POINTER is a special case, and may only be
+ // queried with GetBufferPointerv
+ case GL_BUFFER_ACCESS_FLAGS:
+ case GL_BUFFER_MAP_OFFSET:
+ case GL_BUFFER_MAP_LENGTH:
+ return (context->getClientMajorVersion() >= 3) || extensions.mapBufferRange;
+
+ default:
+ return false;
+ }
+}
+
bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level)
{
const auto &caps = context->getCaps();
@@ -1513,75 +394,6 @@ bool ValidCompressedImageSize(const ValidationContext *context,
return true;
}
-bool ValidImageDataSize(ValidationContext *context,
- GLenum textureTarget,
- GLsizei width,
- GLsizei height,
- GLsizei depth,
- GLenum internalFormat,
- GLenum type,
- const GLvoid *pixels,
- GLsizei imageSize)
-{
- gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER);
- if (pixelUnpackBuffer == nullptr && imageSize < 0)
- {
- // Checks are not required
- return true;
- }
-
- // ...the data would be unpacked from the buffer object such that the memory reads required
- // would exceed the data store size.
- GLenum sizedFormat = GetSizedInternalFormat(internalFormat, type);
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat);
- const gl::Extents size(width, height, depth);
- const auto &unpack = context->getGLState().getUnpackState();
-
- bool targetIs3D = textureTarget == GL_TEXTURE_3D || textureTarget == GL_TEXTURE_2D_ARRAY;
- auto endByteOrErr = formatInfo.computePackUnpackEndByte(size, unpack, targetIs3D);
- if (endByteOrErr.isError())
- {
- context->handleError(endByteOrErr.getError());
- return false;
- }
-
- GLuint endByte = endByteOrErr.getResult();
-
- if (pixelUnpackBuffer)
- {
- CheckedNumeric<size_t> checkedEndByte(endByteOrErr.getResult());
- CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
- checkedEndByte += checkedOffset;
-
- if (!checkedEndByte.IsValid() ||
- (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
- {
- // Overflow past the end of the buffer
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
- }
- else
- {
- ASSERT(imageSize >= 0);
- if (pixels == nullptr && imageSize != 0)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "imageSize must be 0 if no texture data is provided."));
- return false;
- }
-
- if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "imageSize must be at least %u.", endByte));
- return false;
- }
- }
-
- return true;
-}
-
bool ValidQueryType(const Context *context, GLenum queryType)
{
static_assert(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT, "GL extension enums not equal.");
@@ -1603,7 +415,7 @@ bool ValidQueryType(const Context *context, GLenum queryType)
}
}
-Program *GetValidProgram(ValidationContext *context, GLuint id)
+Program *GetValidProgram(Context *context, GLuint id)
{
// ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the
// error INVALID_VALUE if the provided name is not the name of either a shader or program object and
@@ -1627,7 +439,7 @@ Program *GetValidProgram(ValidationContext *context, GLuint id)
return validProgram;
}
-Shader *GetValidShader(ValidationContext *context, GLuint id)
+Shader *GetValidShader(Context *context, GLuint id)
{
// See ValidProgram for spec details.
@@ -1670,8 +482,7 @@ bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
break;
case GL_DEPTH_STENCIL_ATTACHMENT:
- if (!context->getExtensions().webglCompatibility &&
- context->getClientMajorVersion() < 3)
+ if (context->getClientMajorVersion() < 3)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
@@ -2004,6 +815,264 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context,
return true;
}
+bool ValidateGetVertexAttribParameters(Context *context, GLenum pname)
+{
+ switch (pname)
+ {
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ case GL_CURRENT_VERTEX_ATTRIB:
+ return true;
+
+ case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+ // Don't verify ES3 context because GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE uses
+ // the same constant.
+ static_assert(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
+ "ANGLE extension enums not equal to GL enums.");
+ return true;
+
+ case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ return true;
+
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+}
+
+bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pname, GLint param)
+{
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_SWIZZLE_R:
+ case GL_TEXTURE_SWIZZLE_G:
+ case GL_TEXTURE_SWIZZLE_B:
+ case GL_TEXTURE_SWIZZLE_A:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ if (target == GL_TEXTURE_EXTERNAL_OES && !context->getExtensions().eglImageExternalEssl3)
+ {
+ context->handleError(Error(GL_INVALID_ENUM,
+ "ES3 texture parameters are not available without "
+ "GL_OES_EGL_image_external_essl3."));
+ return false;
+ }
+ break;
+
+ default: break;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ switch (param)
+ {
+ case GL_CLAMP_TO_EDGE:
+ return true;
+ case GL_REPEAT:
+ case GL_MIRRORED_REPEAT:
+ if (target == GL_TEXTURE_EXTERNAL_OES)
+ {
+ // OES_EGL_image_external specifies this error.
+ context->handleError(Error(
+ GL_INVALID_ENUM, "external textures only support CLAMP_TO_EDGE wrap mode"));
+ return false;
+ }
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+
+ case GL_TEXTURE_MIN_FILTER:
+ switch (param)
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ return true;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if (target == GL_TEXTURE_EXTERNAL_OES)
+ {
+ // OES_EGL_image_external specifies this error.
+ context->handleError(
+ Error(GL_INVALID_ENUM,
+ "external textures only support NEAREST and LINEAR filtering"));
+ return false;
+ }
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MAG_FILTER:
+ switch (param)
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_USAGE_ANGLE:
+ switch (param)
+ {
+ case GL_NONE:
+ case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (!context->getExtensions().textureFilterAnisotropic)
+ {
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+
+ // we assume the parameter passed to this validation method is truncated, not rounded
+ if (param < 1)
+ {
+ context->handleError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+ return true;
+
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ // any value is permissible
+ return true;
+
+ case GL_TEXTURE_COMPARE_MODE:
+ // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
+ switch (param)
+ {
+ case GL_NONE:
+ case GL_COMPARE_REF_TO_TEXTURE:
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_COMPARE_FUNC:
+ // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
+ switch (param)
+ {
+ case GL_LEQUAL:
+ case GL_GEQUAL:
+ case GL_LESS:
+ case GL_GREATER:
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_ALWAYS:
+ case GL_NEVER:
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_SWIZZLE_R:
+ case GL_TEXTURE_SWIZZLE_G:
+ case GL_TEXTURE_SWIZZLE_B:
+ case GL_TEXTURE_SWIZZLE_A:
+ switch (param)
+ {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_ZERO:
+ case GL_ONE:
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ if (param < 0)
+ {
+ context->handleError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+ if (target == GL_TEXTURE_EXTERNAL_OES && param != 0)
+ {
+ context->handleError(
+ Error(GL_INVALID_OPERATION, "Base level must be 0 for external textures."));
+ return false;
+ }
+ return true;
+
+ case GL_TEXTURE_MAX_LEVEL:
+ if (param < 0)
+ {
+ context->handleError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+ return true;
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+}
+
+bool ValidateSamplerObjectParameter(gl::Context *context, GLenum pname)
+{
+ switch (pname)
+ {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+ return true;
+
+ default:
+ context->handleError(Error(GL_INVALID_ENUM));
+ return false;
+ }
+}
+
bool ValidateReadPixels(ValidationContext *context,
GLint x,
GLint y,
@@ -2013,33 +1082,53 @@ bool ValidateReadPixels(ValidationContext *context,
GLenum type,
GLvoid *pixels)
{
- return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, pixels);
-}
+ if (width < 0 || height < 0)
+ {
+ context->handleError(Error(GL_INVALID_VALUE, "width and height must be positive"));
+ return false;
+ }
-bool ValidateReadPixelsRobustANGLE(ValidationContext *context,
- GLint x,
- GLint y,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- GLsizei bufSize,
- GLsizei *length,
- GLvoid *pixels)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
+ auto readFramebuffer = context->getGLState().getReadFramebuffer();
+
+ if (readFramebuffer->checkStatus(context->getContextState()) != GL_FRAMEBUFFER_COMPLETE)
{
+ context->handleError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
}
- if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, length,
- pixels))
+ if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context->getContextState()) != 0)
{
+ context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
- if (!ValidateRobustBufferSize(context, bufSize, *length))
+ const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
+ ASSERT(framebuffer);
+
+ if (framebuffer->getReadBufferState() == GL_NONE)
{
+ context->handleError(Error(GL_INVALID_OPERATION, "Read buffer is GL_NONE"));
+ return false;
+ }
+
+ const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
+ if (!readBuffer)
+ {
+ context->handleError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ GLenum currentFormat = framebuffer->getImplementationColorReadFormat();
+ GLenum currentType = framebuffer->getImplementationColorReadType();
+ GLenum currentInternalFormat = readBuffer->getFormat().asSized();
+ GLuint clientVersion = context->getClientMajorVersion();
+
+ bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) :
+ ValidES3ReadFormatType(context, currentInternalFormat, format, type);
+
+ if (!(currentFormat == format && currentType == type) && !validReadFormat)
+ {
+ context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
@@ -2062,37 +1151,35 @@ bool ValidateReadnPixelsEXT(Context *context,
return false;
}
- return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
- pixels);
-}
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+ const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
-bool ValidateReadnPixelsRobustANGLE(ValidationContext *context,
- GLint x,
- GLint y,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- GLsizei bufSize,
- GLsizei *length,
- GLvoid *data)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
+ auto outputPitchOrErr =
+ sizedFormatInfo.computeRowPitch(type, width, context->getGLState().getPackAlignment(),
+ context->getGLState().getPackRowLength());
+
+ if (outputPitchOrErr.isError())
{
+ context->handleError(outputPitchOrErr.getError());
return false;
}
- if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, length, data))
+ CheckedNumeric<GLuint> checkedOutputPitch(outputPitchOrErr.getResult());
+ auto checkedRequiredSize = checkedOutputPitch * height;
+ if (!checkedRequiredSize.IsValid())
{
+ context->handleError(Error(GL_INVALID_OPERATION, "Unsigned multiplication overflow."));
return false;
}
- if (!ValidateRobustBufferSize(context, bufSize, *length))
+ // sized query sanity check
+ if (checkedRequiredSize.ValueOrDie() > static_cast<GLuint>(bufSize))
{
+ context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
- return true;
+ return ValidateReadPixels(context, x, y, width, height, format, type, pixels);
}
bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n)
@@ -2247,13 +1334,8 @@ bool ValidateQueryCounterEXT(Context *context, GLuint id, GLenum target)
return true;
}
-bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname, GLsizei *numParams)
+bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname)
{
- if (numParams)
- {
- *numParams = 0;
- }
-
if (!ValidQueryType(context, target) && target != GL_TIMESTAMP_EXT)
{
context->handleError(Error(GL_INVALID_ENUM, "Invalid query type"));
@@ -2283,12 +1365,6 @@ bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname, GLsiz
return false;
}
- if (numParams)
- {
- // All queries return only one value
- *numParams = 1;
- }
-
return true;
}
@@ -2301,41 +1377,11 @@ bool ValidateGetQueryivEXT(Context *context, GLenum target, GLenum pname, GLint
return false;
}
- return ValidateGetQueryivBase(context, target, pname, nullptr);
+ return ValidateGetQueryivBase(context, target, pname);
}
-bool ValidateGetQueryivRobustANGLE(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
+bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname)
{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetQueryivBase(context, target, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
-{
- if (numParams)
- {
- *numParams = 0;
- }
-
Query *queryObject = context->getQuery(id, false, GL_NONE);
if (!queryObject)
@@ -2361,11 +1407,6 @@ bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname,
return false;
}
- if (numParams)
- {
- *numParams = 1;
- }
-
return true;
}
@@ -2376,38 +1417,7 @@ bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLin
context->handleError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled"));
return false;
}
- return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
-}
-
-bool ValidateGetQueryObjectivRobustANGLE(Context *context,
- GLuint id,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!context->getExtensions().disjointTimerQuery)
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled"));
- return false;
- }
-
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
+ return ValidateGetQueryObjectValueBase(context, id, pname);
}
bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
@@ -2418,39 +1428,7 @@ bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLu
context->handleError(Error(GL_INVALID_OPERATION, "Query extension not enabled"));
return false;
}
- return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
-}
-
-bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
- GLuint id,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLuint *params)
-{
- if (!context->getExtensions().disjointTimerQuery &&
- !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Query extension not enabled"));
- return false;
- }
-
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
+ return ValidateGetQueryObjectValueBase(context, id, pname);
}
bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
@@ -2460,38 +1438,7 @@ bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GL
context->handleError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled"));
return false;
}
- return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
-}
-
-bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
- GLuint id,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint64 *params)
-{
- if (!context->getExtensions().disjointTimerQuery)
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled"));
- return false;
- }
-
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
+ return ValidateGetQueryObjectValueBase(context, id, pname);
}
bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
@@ -2501,38 +1448,7 @@ bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, G
context->handleError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled"));
return false;
}
- return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
-}
-
-bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
- GLuint id,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLuint64 *params)
-{
- if (!context->getExtensions().disjointTimerQuery)
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled"));
- return false;
- }
-
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetQueryObjectValueBase(context, id, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
+ return ValidateGetQueryObjectValueBase(context, id, pname);
}
static bool ValidateUniformCommonBase(gl::Context *context,
@@ -2671,12 +1587,10 @@ bool ValidateStateQuery(ValidationContext *context,
case GL_TEXTURE_BINDING_2D_ARRAY:
break;
case GL_TEXTURE_BINDING_EXTERNAL_OES:
- if (!context->getExtensions().eglStreamConsumerExternal &&
- !context->getExtensions().eglImageExternal)
+ if (!context->getExtensions().eglStreamConsumerExternal)
{
- context->handleError(Error(GL_INVALID_ENUM,
- "Neither NV_EGL_stream_consumer_external nor "
- "GL_OES_EGL_image_external extensions enabled"));
+ context->handleError(
+ Error(GL_INVALID_ENUM, "NV_EGL_stream_consumer_external extension not enabled"));
return false;
}
break;
@@ -2714,31 +1628,7 @@ bool ValidateStateQuery(ValidationContext *context,
}
// pname is valid, but there are no parameters to return
- if (*numParams == 0)
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateRobustStateQuery(ValidationContext *context,
- GLenum pname,
- GLsizei bufSize,
- GLenum *nativeType,
- unsigned int *numParams)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateStateQuery(context, pname, nativeType, numParams))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *numParams))
+ if (numParams == 0)
{
return false;
}
@@ -2882,7 +1772,7 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context,
return false;
}
- if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+ if (!formatInfo.textureSupport(context->getClientMajorVersion(), context->getExtensions()))
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
@@ -3219,7 +2109,7 @@ bool ValidateDrawElements(ValidationContext *context,
return false;
}
- if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRangeOut->end + 1)))
+ if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRangeOut->vertexCount())))
{
return false;
}
@@ -3426,28 +2316,13 @@ bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLin
return ValidateGetUniformBase(context, program, location);
}
-static bool ValidateSizedGetUniform(Context *context,
- GLuint program,
- GLint location,
- GLsizei bufSize,
- GLsizei *length)
+static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint location, GLsizei bufSize)
{
- if (length)
- {
- *length = 0;
- }
-
if (!ValidateGetUniformBase(context, program, location))
{
return false;
}
- if (bufSize < 0)
- {
- context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
- return false;
- }
-
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
@@ -3456,82 +2331,21 @@ static bool ValidateSizedGetUniform(Context *context,
size_t requiredBytes = VariableExternalSize(uniform.type);
if (static_cast<size_t>(bufSize) < requiredBytes)
{
- context->handleError(
- Error(GL_INVALID_OPERATION, "bufSize of at least %u is required.", requiredBytes));
+ context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
- if (length)
- {
- *length = VariableComponentCount(uniform.type);
- }
-
return true;
}
bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
{
- return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
+ return ValidateSizedGetUniform(context, program, location, bufSize);
}
bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params)
{
- return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
-}
-
-bool ValidateGetUniformfvRobustANGLE(Context *context,
- GLuint program,
- GLint location,
- GLsizei bufSize,
- GLsizei *length,
- GLfloat *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- // bufSize is validated in ValidateSizedGetUniform
- return ValidateSizedGetUniform(context, program, location, bufSize, length);
-}
-
-bool ValidateGetUniformivRobustANGLE(Context *context,
- GLuint program,
- GLint location,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- // bufSize is validated in ValidateSizedGetUniform
- return ValidateSizedGetUniform(context, program, location, bufSize, length);
-}
-
-bool ValidateGetUniformuivRobustANGLE(Context *context,
- GLuint program,
- GLint location,
- GLsizei bufSize,
- GLsizei *length,
- GLuint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "Entry point requires at least OpenGL ES 3.0."));
- return false;
- }
-
- // bufSize is validated in ValidateSizedGetUniform
- return ValidateSizedGetUniform(context, program, location, bufSize, length);
+ return ValidateSizedGetUniform(context, program, location, bufSize);
}
bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments,
@@ -3979,56 +2793,32 @@ bool ValidateCopyTexSubImage2D(Context *context,
yoffset, 0, x, y, width, height, 0);
}
-bool ValidateGetBufferPointervBase(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei *length,
- void **params)
+bool ValidateGetBufferPointervBase(Context *context, GLenum target, GLenum pname, void **params)
{
- if (length)
- {
- *length = 0;
- }
-
- if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION,
- "Context does not support OpenGL ES 3.0 or GL_OES_map_buffer is not enabled."));
- return false;
- }
-
if (!ValidBufferTarget(context, target))
{
context->handleError(Error(GL_INVALID_ENUM, "Buffer target not valid: 0x%X", target));
return false;
}
- switch (pname)
+ if (pname != GL_BUFFER_MAP_POINTER)
{
- case GL_BUFFER_MAP_POINTER:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown pname."));
- return false;
+ context->handleError(Error(GL_INVALID_ENUM, "pname not valid: 0x%X", pname));
+ return false;
}
+ Buffer *buffer = context->getGLState().getTargetBuffer(target);
+
// GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
// target bound to zero generate an INVALID_OPERATION error."
// GLES 3.1 section 6.6 explicitly specifies this error.
- if (context->getGLState().getTargetBuffer(target) == nullptr)
+ if (!buffer)
{
context->handleError(
Error(GL_INVALID_OPERATION, "Can not get pointer for reserved buffer name zero."));
return false;
}
- if (length)
- {
- *length = 1;
- }
-
return true;
}
@@ -4310,981 +3100,4 @@ bool ValidateGenOrDelete(Context *context, GLint n)
return true;
}
-bool ValidateEnable(Context *context, GLenum cap)
-{
- if (!ValidCap(context, cap, false))
- {
- context->handleError(Error(GL_INVALID_ENUM, "Invalid cap."));
- return false;
- }
-
- if (context->getLimitations().noSampleAlphaToCoverageSupport &&
- cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
- {
- const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
- context->handleError(Error(GL_INVALID_OPERATION, errorMessage));
-
- // We also output an error message to the debugger window if tracing is active, so that
- // developers can see the error message.
- ERR("%s", errorMessage);
- return false;
- }
-
- return true;
-}
-
-bool ValidateDisable(Context *context, GLenum cap)
-{
- if (!ValidCap(context, cap, false))
- {
- context->handleError(Error(GL_INVALID_ENUM, "Invalid cap."));
- return false;
- }
-
- return true;
-}
-
-bool ValidateIsEnabled(Context *context, GLenum cap)
-{
- if (!ValidCap(context, cap, true))
- {
- context->handleError(Error(GL_INVALID_ENUM, "Invalid cap."));
- return false;
- }
-
- return true;
-}
-
-bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize)
-{
- if (!context->getExtensions().robustClientMemory)
- {
- context->handleError(
- Error(GL_INVALID_OPERATION, "GL_ANGLE_robust_client_memory is not available."));
- return false;
- }
-
- if (bufSize < 0)
- {
- context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative."));
- return false;
- }
-
- return true;
-}
-
-bool ValidateRobustBufferSize(ValidationContext *context, GLsizei bufSize, GLsizei numParams)
-{
- if (bufSize < numParams)
- {
- context->handleError(Error(GL_INVALID_OPERATION,
- "%u parameters are required but %i were provided.", numParams,
- bufSize));
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
- GLenum target,
- GLenum attachment,
- GLenum pname,
- GLsizei *numParams)
-{
- // Only one parameter is returned from glGetFramebufferAttachmentParameteriv
- *numParams = 1;
-
- if (!ValidFramebufferTarget(target))
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
-
- int clientVersion = context->getClientMajorVersion();
-
- switch (pname)
- {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
- if (clientVersion < 3 && !context->getExtensions().sRGB)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
- if (clientVersion < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
-
- // Determine if the attachment is a valid enum
- switch (attachment)
- {
- case GL_BACK:
- case GL_FRONT:
- case GL_DEPTH:
- case GL_STENCIL:
- case GL_DEPTH_STENCIL_ATTACHMENT:
- if (clientVersion < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- break;
-
- default:
- if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
- (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
- }
-
- const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
- ASSERT(framebuffer);
-
- if (framebuffer->id() == 0)
- {
- if (clientVersion < 3)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- switch (attachment)
- {
- case GL_BACK:
- case GL_DEPTH:
- case GL_STENCIL:
- break;
-
- default:
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
- }
- else
- {
- if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
- {
- // Valid attachment query
- }
- else
- {
- switch (attachment)
- {
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- break;
-
- case GL_DEPTH_STENCIL_ATTACHMENT:
- if (!framebuffer->hasValidDepthStencil())
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
- }
- }
-
- const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
- if (attachmentObject)
- {
- ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
- attachmentObject->type() == GL_TEXTURE ||
- attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
-
- switch (pname)
- {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- if (attachmentObject->type() != GL_RENDERBUFFER &&
- attachmentObject->type() != GL_TEXTURE)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- if (attachmentObject->type() != GL_TEXTURE)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- if (attachmentObject->type() != GL_TEXTURE)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
- if (attachmentObject->type() != GL_TEXTURE)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- default:
- break;
- }
- }
- else
- {
- // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
- // is NONE, then querying any other pname will generate INVALID_ENUM.
-
- // ES 3.0.2 spec pg 235 states that if the attachment type is none,
- // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
- // INVALID_OPERATION for all other pnames
-
- switch (pname)
- {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- if (clientVersion < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- break;
-
- default:
- if (clientVersion < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM));
- return false;
- }
- else
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context,
- GLenum target,
- GLenum attachment,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *numParams)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetFramebufferAttachmentParameteriv(context, target, attachment, pname, numParams))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *numParams))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetBufferParameteriv(ValidationContext *context,
- GLenum target,
- GLenum pname,
- GLint *params)
-{
- return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
-}
-
-bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetBufferParameteri64v(ValidationContext *context,
- GLenum target,
- GLenum pname,
- GLint64 *params)
-{
- return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
-}
-
-bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint64 *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetBufferParameterBase(context, target, pname, false, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
-{
- // Currently, all GetProgramiv queries return 1 parameter
- *numParams = 1;
-
- Program *programObject = GetValidProgram(context, program);
- if (!programObject)
- {
- return false;
- }
-
- switch (pname)
- {
- case GL_DELETE_STATUS:
- case GL_LINK_STATUS:
- case GL_VALIDATE_STATUS:
- case GL_INFO_LOG_LENGTH:
- case GL_ATTACHED_SHADERS:
- case GL_ACTIVE_ATTRIBUTES:
- case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
- case GL_ACTIVE_UNIFORMS:
- case GL_ACTIVE_UNIFORM_MAX_LENGTH:
- break;
-
- case GL_PROGRAM_BINARY_LENGTH:
- if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
- {
- context->handleError(Error(GL_INVALID_ENUM,
- "Querying GL_PROGRAM_BINARY_LENGTH requires "
- "GL_OES_get_program_binary or ES 3.0."));
- return false;
- }
- break;
-
- case GL_ACTIVE_UNIFORM_BLOCKS:
- case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
- case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
- case GL_TRANSFORM_FEEDBACK_VARYINGS:
- case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
- case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
- if (context->getClientMajorVersion() < 3)
- {
- context->handleError(Error(GL_INVALID_ENUM, "Querying requires at least ES 3.0."));
- return false;
- }
- break;
-
- default:
- context->handleError(Error(GL_INVALID_ENUM, "Unknown parameter name."));
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetProgramivRobustANGLE(Context *context,
- GLuint program,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *numParams)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetProgramiv(context, program, pname, numParams))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *numParams))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetRenderbufferParameteriv(Context *context,
- GLenum target,
- GLenum pname,
- GLint *params)
-{
- return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
-}
-
-bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetRenderbufferParameterivBase(context, target, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
-{
- return ValidateGetShaderivBase(context, shader, pname, nullptr);
-}
-
-bool ValidateGetShaderivRobustANGLE(Context *context,
- GLuint shader,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetShaderivBase(context, shader, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
-{
- return ValidateGetTexParameterBase(context, target, pname, nullptr);
-}
-
-bool ValidateGetTexParameterfvRobustANGLE(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLfloat *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetTexParameterBase(context, target, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
-{
- return ValidateGetTexParameterBase(context, target, pname, nullptr);
-}
-
-bool ValidateGetTexParameterivRobustANGLE(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetTexParameterBase(context, target, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
-{
- return ValidateTexParameterBase(context, target, pname, -1, &param);
-}
-
-bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
-{
- return ValidateTexParameterBase(context, target, pname, -1, params);
-}
-
-bool ValidateTexParameterfvRobustANGLE(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- const GLfloat *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- return ValidateTexParameterBase(context, target, pname, bufSize, params);
-}
-
-bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
-{
- return ValidateTexParameterBase(context, target, pname, -1, &param);
-}
-
-bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
-{
- return ValidateTexParameterBase(context, target, pname, -1, params);
-}
-
-bool ValidateTexParameterivRobustANGLE(Context *context,
- GLenum target,
- GLenum pname,
- GLsizei bufSize,
- const GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- return ValidateTexParameterBase(context, target, pname, bufSize, params);
-}
-
-bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params)
-{
- return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
-}
-
-bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
- GLuint sampler,
- GLenum pname,
- GLuint bufSize,
- GLsizei *length,
- GLfloat *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetSamplerParameterBase(context, sampler, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, GLint *params)
-{
- return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr);
-}
-
-bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
- GLuint sampler,
- GLenum pname,
- GLuint bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetSamplerParameterBase(context, sampler, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param)
-{
- return ValidateSamplerParameterBase(context, sampler, pname, -1, &param);
-}
-
-bool ValidateSamplerParameterfv(Context *context,
- GLuint sampler,
- GLenum pname,
- const GLfloat *params)
-{
- return ValidateSamplerParameterBase(context, sampler, pname, -1, params);
-}
-
-bool ValidateSamplerParameterfvRobustANGLE(Context *context,
- GLuint sampler,
- GLenum pname,
- GLsizei bufSize,
- const GLfloat *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
-}
-
-bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param)
-{
- return ValidateSamplerParameterBase(context, sampler, pname, -1, &param);
-}
-
-bool ValidateSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, const GLint *params)
-{
- return ValidateSamplerParameterBase(context, sampler, pname, -1, params);
-}
-
-bool ValidateSamplerParameterivRobustANGLE(Context *context,
- GLuint sampler,
- GLenum pname,
- GLsizei bufSize,
- const GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
-}
-
-bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
-{
- return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
-}
-
-bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
- GLuint index,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLfloat *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetVertexAttribBase(context, index, pname, length, false, false))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
-{
- return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
-}
-
-bool ValidateGetVertexAttribivRobustANGLE(Context *context,
- GLuint index,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetVertexAttribBase(context, index, pname, length, false, false))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
-{
- return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
-}
-
-bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
- GLuint index,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- void **pointer)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetVertexAttribBase(context, index, pname, length, true, false))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params)
-{
- return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
-}
-
-bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
- GLuint index,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetVertexAttribBase(context, index, pname, length, false, true))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params)
-{
- return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true);
-}
-
-bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
- GLuint index,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLuint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetVertexAttribBase(context, index, pname, length, false, true))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetActiveUniformBlockiv(Context *context,
- GLuint program,
- GLuint uniformBlockIndex,
- GLenum pname,
- GLint *params)
-{
- return ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, nullptr);
-}
-
-bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
- GLuint program,
- GLuint uniformBlockIndex,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
-bool ValidateGetInternalFormativ(Context *context,
- GLenum target,
- GLenum internalformat,
- GLenum pname,
- GLsizei bufSize,
- GLint *params)
-{
- return ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
- nullptr);
-}
-
-bool ValidateGetInternalFormativRobustANGLE(Context *context,
- GLenum target,
- GLenum internalformat,
- GLenum pname,
- GLsizei bufSize,
- GLsizei *length,
- GLint *params)
-{
- if (!ValidateRobustEntryPoint(context, bufSize))
- {
- return false;
- }
-
- if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize, length))
- {
- return false;
- }
-
- if (!ValidateRobustBufferSize(context, bufSize, *length))
- {
- return false;
- }
-
- return true;
-}
-
} // namespace gl