blob: fe76965a710659fa19d84aa2b97ab9b68ed7ec36 [file] [log] [blame]
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// validationESEXT.cpp: Validation functions for OpenGL ES extension entry points.
#include "libANGLE/validationESEXT_autogen.h"
#include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h"
#include "libANGLE/MemoryObject.h"
#include "libANGLE/validationES.h"
#include "libANGLE/validationES2.h"
#include "libANGLE/validationES3.h"
#include "libANGLE/validationES31.h"
#include "libANGLE/validationES32.h"
namespace gl
{
using namespace err;
namespace
{
template <typename ObjectT>
bool ValidateGetImageFormatAndType(const Context *context, ObjectT *obj, GLenum format, GLenum type)
{
GLenum implFormat = obj->getImplementationColorReadFormat(context);
if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE))
{
context->validationError(GL_INVALID_ENUM, kInvalidFormat);
return false;
}
GLenum implType = obj->getImplementationColorReadType(context);
if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
// Format/type combinations are not yet validated.
return true;
}
bool IsValidImageLayout(ImageLayout layout)
{
switch (layout)
{
case ImageLayout::Undefined:
case ImageLayout::General:
case ImageLayout::ColorAttachment:
case ImageLayout::DepthStencilAttachment:
case ImageLayout::DepthStencilReadOnlyAttachment:
case ImageLayout::ShaderReadOnly:
case ImageLayout::TransferSrc:
case ImageLayout::TransferDst:
case ImageLayout::DepthReadOnlyStencilAttachment:
case ImageLayout::DepthAttachmentStencilReadOnly:
return true;
default:
return false;
}
}
bool IsValidMemoryObjectParamater(const Context *context, GLenum pname)
{
switch (pname)
{
case GL_DEDICATED_MEMORY_OBJECT_EXT:
return true;
case GL_PROTECTED_MEMORY_OBJECT_EXT:
if (!context->getExtensions().protectedTexturesEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return true;
default:
return false;
}
}
bool ValidateObjectIdentifierAndName(const Context *context, GLenum identifier, GLuint name)
{
bool isGLES11 = context->getClientVersion() == Version(1, 1);
bool isGLES3 = context->getClientMajorVersion() >= 3;
bool isGLES31 = context->getClientVersion() >= Version(3, 1);
switch (identifier)
{
case GL_BUFFER_OBJECT_EXT:
if (context->getBuffer({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidBufferName);
return false;
}
return true;
case GL_SHADER_OBJECT_EXT:
if (isGLES11)
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
if (context->getShader({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
return false;
}
return true;
case GL_PROGRAM_OBJECT_EXT:
if (isGLES11)
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
if (context->getProgramNoResolveLink({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidProgramName);
return false;
}
return true;
case GL_VERTEX_ARRAY_OBJECT_EXT:
if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES)
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
if (context->getVertexArray({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidVertexArrayName);
return false;
}
return true;
case GL_QUERY_OBJECT_EXT:
if (!isGLES3 && !context->getExtensions().occlusionQueryBoolean)
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
if (context->getQuery({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidQueryName);
return false;
}
return true;
case GL_TRANSFORM_FEEDBACK:
if (!isGLES3)
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
if (context->getTransformFeedback({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidTransformFeedbackName);
return false;
}
return true;
case GL_SAMPLER:
if (!isGLES3)
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
if (context->getSampler({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidSamplerName);
return false;
}
return true;
case GL_TEXTURE:
if (context->getTexture({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidTextureName);
return false;
}
return true;
case GL_RENDERBUFFER:
if (!context->isRenderbuffer({name}))
{
context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferName);
return false;
}
return true;
case GL_FRAMEBUFFER:
if (context->getFramebuffer({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidFramebufferName);
return false;
}
return true;
case GL_PROGRAM_PIPELINE_OBJECT_EXT:
if (!isGLES31 && !context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_ENUM, kInvalidType);
return false;
}
if (context->getProgramPipeline({name}) == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kInvalidProgramPipelineName);
return false;
}
return true;
default:
context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
return false;
}
}
} // namespace
bool ValidateGetTexImageANGLE(const Context *context,
TextureTarget target,
GLint level,
GLenum format,
GLenum type,
const void *pixels)
{
if (!context->getExtensions().getImageANGLE)
{
context->validationError(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
return false;
}
if (!ValidTexture2DDestinationTarget(context, target) &&
!ValidTexture3DDestinationTarget(context, target))
{
context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
return false;
}
if (level < 0)
{
context->validationError(GL_INVALID_VALUE, kNegativeLevel);
return false;
}
TextureType textureType = TextureTargetToType(target);
if (!ValidMipLevel(context, textureType, level))
{
context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
return false;
}
Texture *texture = context->getTextureByTarget(target);
if (!ValidateGetImageFormatAndType(context, texture, format, type))
{
return false;
}
GLsizei width = static_cast<GLsizei>(texture->getWidth(target, level));
GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level));
if (!ValidatePixelPack(context, format, type, 0, 0, width, height, -1, nullptr, pixels))
{
return false;
}
return true;
}
bool ValidateGetRenderbufferImageANGLE(const Context *context,
GLenum target,
GLenum format,
GLenum type,
const void *pixels)
{
if (!context->getExtensions().getImageANGLE)
{
context->validationError(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
return false;
}
if (target != GL_RENDERBUFFER)
{
context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
return false;
}
Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
if (!ValidateGetImageFormatAndType(context, renderbuffer, format, type))
{
return false;
}
GLsizei width = renderbuffer->getWidth();
GLsizei height = renderbuffer->getHeight();
if (!ValidatePixelPack(context, format, type, 0, 0, width, height, -1, nullptr, pixels))
{
return false;
}
return true;
}
bool ValidateDrawElementsBaseVertexEXT(const Context *context,
PrimitiveMode mode,
GLsizei count,
DrawElementsType type,
const void *indices,
GLint basevertex)
{
if (!context->getExtensions().drawElementsBaseVertexAny())
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
}
bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context,
PrimitiveMode mode,
GLsizei count,
DrawElementsType type,
const void *indices,
GLsizei instancecount,
GLint basevertex)
{
if (!context->getExtensions().drawElementsBaseVertexAny())
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, instancecount);
}
bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context,
PrimitiveMode mode,
GLuint start,
GLuint end,
GLsizei count,
DrawElementsType type,
const void *indices,
GLint basevertex)
{
if (!context->getExtensions().drawElementsBaseVertexAny())
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
if (end < start)
{
context->validationError(GL_INVALID_VALUE, kInvalidElementRange);
return false;
}
if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
{
return false;
}
// Skip range checks for no-op calls.
if (count <= 0)
{
return true;
}
// Note that resolving the index range is a bit slow. We should probably optimize this.
IndexRange indexRange;
ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
indices, &indexRange));
if (indexRange.end > end || indexRange.start < start)
{
// GL spec says that behavior in this case is undefined - generating an error is fine.
context->validationError(GL_INVALID_OPERATION, kExceedsElementRange);
return false;
}
return true;
}
bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context,
PrimitiveMode mode,
const GLsizei *count,
DrawElementsType type,
const void *const *indices,
GLsizei drawcount,
const GLint *basevertex)
{
return true;
}
bool ValidateDrawElementsBaseVertexOES(const Context *context,
PrimitiveMode mode,
GLsizei count,
DrawElementsType type,
const void *indices,
GLint basevertex)
{
if (!context->getExtensions().drawElementsBaseVertexAny())
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
}
bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context,
PrimitiveMode mode,
GLsizei count,
DrawElementsType type,
const void *indices,
GLsizei instancecount,
GLint basevertex)
{
if (!context->getExtensions().drawElementsBaseVertexAny())
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, instancecount);
}
bool ValidateDrawRangeElementsBaseVertexOES(const Context *context,
PrimitiveMode mode,
GLuint start,
GLuint end,
GLsizei count,
DrawElementsType type,
const void *indices,
GLint basevertex)
{
if (!context->getExtensions().drawElementsBaseVertexAny())
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
if (end < start)
{
context->validationError(GL_INVALID_VALUE, kInvalidElementRange);
return false;
}
if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
{
return false;
}
// Skip range checks for no-op calls.
if (count <= 0)
{
return true;
}
// Note that resolving the index range is a bit slow. We should probably optimize this.
IndexRange indexRange;
ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
indices, &indexRange));
if (indexRange.end > end || indexRange.start < start)
{
// GL spec says that behavior in this case is undefined - generating an error is fine.
context->validationError(GL_INVALID_OPERATION, kExceedsElementRange);
return false;
}
return true;
}
// GL_KHR_blend_equation_advanced
bool ValidateBlendBarrierKHR(const Context *context)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
bool ValidateBlendEquationSeparateiEXT(const Context *context,
GLuint buf,
GLenum modeRGB,
GLenum modeAlpha)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendEquationSeparatei(context, buf, modeRGB, modeAlpha);
}
bool ValidateBlendEquationiEXT(const Context *context, GLuint buf, GLenum mode)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendEquationi(context, buf, mode);
}
bool ValidateBlendFuncSeparateiEXT(const Context *context,
GLuint buf,
GLenum srcRGB,
GLenum dstRGB,
GLenum srcAlpha,
GLenum dstAlpha)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendFuncSeparatei(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
bool ValidateBlendFunciEXT(const Context *context, GLuint buf, GLenum src, GLenum dst)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendFunci(context, buf, src, dst);
}
bool ValidateColorMaskiEXT(const Context *context,
GLuint index,
GLboolean r,
GLboolean g,
GLboolean b,
GLboolean a)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateColorMaski(context, index, r, g, b, a);
}
bool ValidateDisableiEXT(const Context *context, GLenum target, GLuint index)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateDisablei(context, target, index);
}
bool ValidateEnableiEXT(const Context *context, GLenum target, GLuint index)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateEnablei(context, target, index);
}
bool ValidateIsEnablediEXT(const Context *context, GLenum target, GLuint index)
{
if (!context->getExtensions().drawBuffersIndexedEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateIsEnabledi(context, target, index);
}
bool ValidateBlendEquationSeparateiOES(const Context *context,
GLuint buf,
GLenum modeRGB,
GLenum modeAlpha)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendEquationSeparatei(context, buf, modeRGB, modeAlpha);
}
bool ValidateBlendEquationiOES(const Context *context, GLuint buf, GLenum mode)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendEquationi(context, buf, mode);
}
bool ValidateBlendFuncSeparateiOES(const Context *context,
GLuint buf,
GLenum srcRGB,
GLenum dstRGB,
GLenum srcAlpha,
GLenum dstAlpha)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendFuncSeparatei(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
bool ValidateBlendFunciOES(const Context *context, GLuint buf, GLenum src, GLenum dst)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBlendFunci(context, buf, src, dst);
}
bool ValidateColorMaskiOES(const Context *context,
GLuint index,
GLboolean r,
GLboolean g,
GLboolean b,
GLboolean a)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateColorMaski(context, index, r, g, b, a);
}
bool ValidateDisableiOES(const Context *context, GLenum target, GLuint index)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateDisablei(context, target, index);
}
bool ValidateEnableiOES(const Context *context, GLenum target, GLuint index)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateEnablei(context, target, index);
}
bool ValidateIsEnablediOES(const Context *context, GLenum target, GLuint index)
{
if (!context->getExtensions().drawBuffersIndexedOES)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateIsEnabledi(context, target, index);
}
bool ValidateGetInteger64vEXT(const Context *context, GLenum pname, const GLint64 *data)
{
if (!context->getExtensions().disjointTimerQuery)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
GLenum nativeType = GL_NONE;
unsigned int numParams = 0;
if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
{
return false;
}
return true;
}
bool ValidateCopyImageSubDataEXT(const Context *context,
GLuint srcName,
GLenum srcTarget,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLuint dstName,
GLenum dstTarget,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth)
{
if (!context->getExtensions().copyImageEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateCopyImageSubDataBase(context, srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
srcHeight, srcDepth);
}
bool ValidateCopyImageSubDataOES(const Context *context,
GLuint srcName,
GLenum srcTarget,
GLint srcLevel,
GLint srcX,
GLint srcY,
GLint srcZ,
GLuint dstName,
GLenum dstTarget,
GLint dstLevel,
GLint dstX,
GLint dstY,
GLint dstZ,
GLsizei srcWidth,
GLsizei srcHeight,
GLsizei srcDepth)
{
if (!context->getExtensions().copyImageEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateCopyImageSubDataBase(context, srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
srcHeight, srcDepth);
}
bool ValidateBufferStorageMemEXT(const Context *context,
TextureType target,
GLsizeiptr size,
MemoryObjectID memory,
GLuint64 offset)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
UNIMPLEMENTED();
return false;
}
bool ValidateCreateMemoryObjectsEXT(const Context *context,
GLsizei n,
const MemoryObjectID *memoryObjects)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateGenOrDelete(context, n);
}
bool ValidateDeleteMemoryObjectsEXT(const Context *context,
GLsizei n,
const MemoryObjectID *memoryObjects)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateGenOrDelete(context, n);
}
bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
MemoryObjectID memoryObject,
GLenum pname,
const GLint *params)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
const MemoryObject *memory = context->getMemoryObject(memoryObject);
if (memory == nullptr)
{
context->validationError(GL_INVALID_VALUE, kInvalidMemoryObject);
}
if (!IsValidMemoryObjectParamater(context, pname))
{
context->validationError(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
return false;
}
return true;
}
bool ValidateGetUnsignedBytevEXT(const Context *context, GLenum pname, const GLubyte *data)
{
if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
UNIMPLEMENTED();
return false;
}
bool ValidateGetUnsignedBytei_vEXT(const Context *context,
GLenum target,
GLuint index,
const GLubyte *data)
{
if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
UNIMPLEMENTED();
return false;
}
bool ValidateIsMemoryObjectEXT(const Context *context, MemoryObjectID memoryObject)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return true;
}
bool ValidateMemoryObjectParameterivEXT(const Context *context,
MemoryObjectID memoryObject,
GLenum pname,
const GLint *params)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
const MemoryObject *memory = context->getMemoryObject(memoryObject);
if (memory == nullptr)
{
context->validationError(GL_INVALID_VALUE, kInvalidMemoryObject);
return false;
}
if (memory->isImmutable())
{
context->validationError(GL_INVALID_OPERATION, kImmutableMemoryObject);
return false;
}
if (!IsValidMemoryObjectParamater(context, pname))
{
context->validationError(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
return false;
}
return true;
}
bool ValidateTexStorageMem2DEXT(const Context *context,
TextureType target,
GLsizei levels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
MemoryObjectID memory,
GLuint64 offset)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
if (context->getClientMajorVersion() < 3)
{
return ValidateES2TexStorageParametersBase(context, target, levels, internalFormat, width,
height);
}
ASSERT(context->getClientMajorVersion() >= 3);
return ValidateES3TexStorage2DParameters(context, target, levels, internalFormat, width, height,
1);
}
bool ValidateTexStorageMem3DEXT(const Context *context,
TextureType target,
GLsizei levels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
MemoryObjectID memory,
GLuint64 offset)
{
if (!context->getExtensions().memoryObject)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
UNIMPLEMENTED();
return false;
}
bool ValidateImportMemoryFdEXT(const Context *context,
MemoryObjectID memory,
GLuint64 size,
HandleType handleType,
GLint fd)
{
if (!context->getExtensions().memoryObjectFd)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
switch (handleType)
{
case HandleType::OpaqueFd:
break;
default:
context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
return false;
}
return true;
}
bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
MemoryObjectID memory,
GLuint64 size,
HandleType handleType,
GLuint handle)
{
if (!context->getExtensions().memoryObjectFuchsiaANGLE)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
switch (handleType)
{
case HandleType::ZirconVmo:
break;
default:
context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
return false;
}
return true;
}
bool ValidateDeleteSemaphoresEXT(const Context *context, GLsizei n, const SemaphoreID *semaphores)
{
if (!context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateGenOrDelete(context, n);
}
bool ValidateGenSemaphoresEXT(const Context *context, GLsizei n, const SemaphoreID *semaphores)
{
if (!context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateGenOrDelete(context, n);
}
bool ValidateGetSemaphoreParameterui64vEXT(const Context *context,
SemaphoreID semaphore,
GLenum pname,
const GLuint64 *params)
{
if (!context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
UNIMPLEMENTED();
return false;
}
bool ValidateIsSemaphoreEXT(const Context *context, SemaphoreID semaphore)
{
if (!context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return true;
}
bool ValidateSemaphoreParameterui64vEXT(const Context *context,
SemaphoreID semaphore,
GLenum pname,
const GLuint64 *params)
{
if (!context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
UNIMPLEMENTED();
return false;
}
bool ValidateSignalSemaphoreEXT(const Context *context,
SemaphoreID semaphore,
GLuint numBufferBarriers,
const BufferID *buffers,
GLuint numTextureBarriers,
const TextureID *textures,
const GLenum *dstLayouts)
{
if (!context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
for (GLuint i = 0; i < numTextureBarriers; ++i)
{
if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
{
context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
return false;
}
}
return true;
}
bool ValidateWaitSemaphoreEXT(const Context *context,
SemaphoreID semaphore,
GLuint numBufferBarriers,
const BufferID *buffers,
GLuint numTextureBarriers,
const TextureID *textures,
const GLenum *srcLayouts)
{
if (!context->getExtensions().semaphore)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
for (GLuint i = 0; i < numTextureBarriers; ++i)
{
if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
{
context->validationError(GL_INVALID_ENUM, kInvalidImageLayout);
return false;
}
}
return true;
}
bool ValidateImportSemaphoreFdEXT(const Context *context,
SemaphoreID semaphore,
HandleType handleType,
GLint fd)
{
if (!context->getExtensions().semaphoreFd)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
switch (handleType)
{
case HandleType::OpaqueFd:
break;
default:
context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
return false;
}
return true;
}
bool ValidateGetSamplerParameterIivEXT(const Context *context,
SamplerID samplerPacked,
GLenum pname,
const GLint *params)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateGetSamplerParameterBase(context, samplerPacked, pname, nullptr);
}
bool ValidateGetSamplerParameterIuivEXT(const Context *context,
SamplerID samplerPacked,
GLenum pname,
const GLuint *params)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateGetSamplerParameterBase(context, samplerPacked, pname, nullptr);
}
bool ValidateGetTexParameterIivEXT(const Context *context,
TextureType targetPacked,
GLenum pname,
const GLint *params)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateGetTexParameterBase(context, targetPacked, pname, nullptr);
}
bool ValidateGetTexParameterIuivEXT(const Context *context,
TextureType targetPacked,
GLenum pname,
const GLuint *params)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateGetTexParameterBase(context, targetPacked, pname, nullptr);
}
bool ValidateSamplerParameterIivEXT(const Context *context,
SamplerID samplerPacked,
GLenum pname,
const GLint *param)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateSamplerParameterBase(context, samplerPacked, pname, -1, true, param);
}
bool ValidateSamplerParameterIuivEXT(const Context *context,
SamplerID samplerPacked,
GLenum pname,
const GLuint *param)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateSamplerParameterBase(context, samplerPacked, pname, -1, true, param);
}
bool ValidateTexParameterIivEXT(const Context *context,
TextureType targetPacked,
GLenum pname,
const GLint *params)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateTexParameterBase(context, targetPacked, pname, -1, true, params);
}
bool ValidateTexParameterIuivEXT(const Context *context,
TextureType targetPacked,
GLenum pname,
const GLuint *params)
{
if (context->getClientMajorVersion() < 3)
{
context->validationError(GL_INVALID_OPERATION, kES3Required);
return false;
}
return ValidateTexParameterBase(context, targetPacked, pname, -1, true, params);
}
bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
SemaphoreID semaphore,
HandleType handleType,
GLuint handle)
{
if (!context->getExtensions().semaphoreFuchsiaANGLE)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
switch (handleType)
{
case HandleType::ZirconEvent:
break;
default:
context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
return false;
}
return true;
}
bool ValidateFramebufferFetchBarrierEXT(const Context *context)
{
return true;
}
bool ValidatePatchParameteriEXT(const Context *context, GLenum pname, GLint value)
{
if (!context->getExtensions().tessellationShaderEXT)
{
context->validationError(GL_INVALID_OPERATION, kTessellationShaderExtensionNotEnabled);
return false;
}
if (pname != GL_PATCH_VERTICES)
{
context->validationError(GL_INVALID_ENUM, kInvalidPname);
return false;
}
if (value <= 0)
{
context->validationError(GL_INVALID_VALUE, kInvalidValueNonPositive);
return false;
}
if (value > context->getCaps().maxPatchVertices)
{
context->validationError(GL_INVALID_VALUE, kInvalidValueExceedsMaxPatchSize);
return false;
}
return true;
}
bool ValidateTexStorageMemFlags2DANGLE(const Context *context,
TextureType targetPacked,
GLsizei levels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
MemoryObjectID memoryPacked,
GLuint64 offset,
GLbitfield createFlags,
GLbitfield usageFlags)
{
if (!context->getExtensions().memoryObjectFlagsANGLE)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
if (!ValidateTexStorageMem2DEXT(context, targetPacked, levels, internalFormat, width, height,
memoryPacked, offset))
{
return false;
}
// |createFlags| and |usageFlags| must only have bits specified by the extension.
constexpr GLbitfield kAllCreateFlags =
GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE |
GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE |
GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE |
GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE |
GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE |
GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE |
GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE |
GL_CREATE_SUBSAMPLED_BIT_ANGLE;
if ((createFlags & ~kAllCreateFlags) != 0)
{
context->validationError(GL_INVALID_VALUE, kInvalidExternalCreateFlags);
return false;
}
constexpr GLbitfield kAllUsageFlags =
GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE |
GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE |
GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE |
GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE |
GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE;
if ((usageFlags & ~kAllUsageFlags) != 0)
{
context->validationError(GL_INVALID_VALUE, kInvalidExternalUsageFlags);
return false;
}
return true;
}
bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context,
TextureType targetPacked,
GLsizei samples,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLboolean fixedSampleLocations,
MemoryObjectID memoryPacked,
GLuint64 offset,
GLbitfield createFlags,
GLbitfield usageFlags)
{
UNIMPLEMENTED();
return false;
}
bool ValidateTexStorageMemFlags3DANGLE(const Context *context,
TextureType targetPacked,
GLsizei levels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
MemoryObjectID memoryPacked,
GLuint64 offset,
GLbitfield createFlags,
GLbitfield usageFlags)
{
UNIMPLEMENTED();
return false;
}
bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context,
TextureType targetPacked,
GLsizei samples,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLboolean fixedSampleLocations,
MemoryObjectID memoryPacked,
GLuint64 offset,
GLbitfield createFlags,
GLbitfield usageFlags)
{
UNIMPLEMENTED();
return false;
}
// GL_EXT_buffer_storage
bool ValidateBufferStorageEXT(const Context *context,
BufferBinding targetPacked,
GLsizeiptr size,
const void *data,
GLbitfield flags)
{
if (!context->isValidBufferBinding(targetPacked))
{
context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
return false;
}
if (size <= 0)
{
context->validationError(GL_INVALID_VALUE, kNonPositiveSize);
return false;
}
constexpr GLbitfield kAllUsageFlags =
(GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT);
if ((flags & ~kAllUsageFlags) != 0)
{
context->validationError(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
return false;
}
if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) &&
((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0))
{
context->validationError(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
return false;
}
if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0))
{
context->validationError(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
return false;
}
Buffer *buffer = context->getState().getTargetBuffer(targetPacked);
if (buffer == nullptr)
{
context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
return false;
}
if (buffer->isImmutable())
{
context->validationError(GL_INVALID_OPERATION, kBufferImmutable);
return false;
}
return true;
}
// GL_EXT_clip_control
bool ValidateClipControlEXT(const Context *context, GLenum origin, GLenum depth)
{
if ((origin != GL_LOWER_LEFT_EXT) && (origin != GL_UPPER_LEFT_EXT))
{
context->validationError(GL_INVALID_ENUM, kInvalidOriginEnum);
return false;
}
if ((depth != GL_NEGATIVE_ONE_TO_ONE_EXT) && (depth != GL_ZERO_TO_ONE_EXT))
{
context->validationError(GL_INVALID_ENUM, kInvalidDepthEnum);
return false;
}
return true;
}
// GL_EXT_external_buffer
bool ValidateBufferStorageExternalEXT(const Context *context,
BufferBinding targetPacked,
GLintptr offset,
GLsizeiptr size,
GLeglClientBufferEXT clientBuffer,
GLbitfield flags)
{
if (!ValidateBufferStorageEXT(context, targetPacked, size, nullptr, flags))
{
return false;
}
if (offset != 0)
{
context->validationError(GL_INVALID_VALUE, kExternalBufferInvalidOffset);
return false;
}
if (clientBuffer == nullptr && size > 0)
{
context->validationError(GL_INVALID_VALUE, kClientBufferInvalid);
return false;
}
return true;
}
bool ValidateNamedBufferStorageExternalEXT(const Context *context,
GLuint buffer,
GLintptr offset,
GLsizeiptr size,
GLeglClientBufferEXT clientBuffer,
GLbitfield flags)
{
UNIMPLEMENTED();
return false;
}
// GL_EXT_primitive_bounding_box
bool ValidatePrimitiveBoundingBoxEXT(const Context *context,
GLfloat minX,
GLfloat minY,
GLfloat minZ,
GLfloat minW,
GLfloat maxX,
GLfloat maxY,
GLfloat maxZ,
GLfloat maxW)
{
if (!context->getExtensions().primitiveBoundingBoxEXT)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return true;
}
// GL_EXT_separate_shader_objects
bool ValidateActiveShaderProgramEXT(const Context *context,
ProgramPipelineID pipelinePacked,
ShaderProgramID programPacked)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateActiveShaderProgramBase(context, pipelinePacked, programPacked);
}
bool ValidateBindProgramPipelineEXT(const Context *context, ProgramPipelineID pipelinePacked)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateBindProgramPipelineBase(context, pipelinePacked);
}
bool ValidateCreateShaderProgramvEXT(const Context *context,
ShaderType typePacked,
GLsizei count,
const GLchar **strings)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateCreateShaderProgramvBase(context, typePacked, count, strings);
}
bool ValidateDeleteProgramPipelinesEXT(const Context *context,
GLsizei n,
const ProgramPipelineID *pipelinesPacked)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateDeleteProgramPipelinesBase(context, n, pipelinesPacked);
}
bool ValidateGenProgramPipelinesEXT(const Context *context,
GLsizei n,
const ProgramPipelineID *pipelinesPacked)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateGenProgramPipelinesBase(context, n, pipelinesPacked);
}
bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
ProgramPipelineID pipelinePacked,
GLsizei bufSize,
const GLsizei *length,
const GLchar *infoLog)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateGetProgramPipelineInfoLogBase(context, pipelinePacked, bufSize, length, infoLog);
}
bool ValidateGetProgramPipelineivEXT(const Context *context,
ProgramPipelineID pipelinePacked,
GLenum pname,
const GLint *params)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateGetProgramPipelineivBase(context, pipelinePacked, pname, params);
}
bool ValidateIsProgramPipelineEXT(const Context *context, ProgramPipelineID pipelinePacked)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateIsProgramPipelineBase(context, pipelinePacked);
}
bool ValidateProgramParameteriEXT(const Context *context,
ShaderProgramID programPacked,
GLenum pname,
GLint value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramParameteriBase(context, programPacked, pname, value);
}
bool ValidateProgramUniform1fEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLfloat v0)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform1fBase(context, programPacked, locationPacked, v0);
}
bool ValidateProgramUniform1fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform1fvBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform1iEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLint v0)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform1iBase(context, programPacked, locationPacked, v0);
}
bool ValidateProgramUniform1ivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLint *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform1ivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform1uiEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLuint v0)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform1uiBase(context, programPacked, locationPacked, v0);
}
bool ValidateProgramUniform1uivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLuint *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform1uivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform2fEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLfloat v0,
GLfloat v1)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform2fBase(context, programPacked, locationPacked, v0, v1);
}
bool ValidateProgramUniform2fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform2fvBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform2iEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLint v0,
GLint v1)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform2iBase(context, programPacked, locationPacked, v0, v1);
}
bool ValidateProgramUniform2ivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLint *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform2ivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform2uiEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLuint v0,
GLuint v1)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform2uiBase(context, programPacked, locationPacked, v0, v1);
}
bool ValidateProgramUniform2uivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLuint *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform2uivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform3fEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLfloat v0,
GLfloat v1,
GLfloat v2)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform3fBase(context, programPacked, locationPacked, v0, v1, v2);
}
bool ValidateProgramUniform3fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform3fvBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform3iEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLint v0,
GLint v1,
GLint v2)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform3iBase(context, programPacked, locationPacked, v0, v1, v2);
}
bool ValidateProgramUniform3ivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLint *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform3ivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform3uiEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLuint v0,
GLuint v1,
GLuint v2)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform3uiBase(context, programPacked, locationPacked, v0, v1, v2);
}
bool ValidateProgramUniform3uivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLuint *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform3uivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform4fEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLfloat v0,
GLfloat v1,
GLfloat v2,
GLfloat v3)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform4fBase(context, programPacked, locationPacked, v0, v1, v2, v3);
}
bool ValidateProgramUniform4fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform4fvBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform4iEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLint v0,
GLint v1,
GLint v2,
GLint v3)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform4iBase(context, programPacked, locationPacked, v0, v1, v2, v3);
}
bool ValidateProgramUniform4ivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLint *value)
{
return ValidateProgramUniform4ivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniform4uiEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLuint v0,
GLuint v1,
GLuint v2,
GLuint v3)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniform4uiBase(context, programPacked, locationPacked, v0, v1, v2, v3);
}
bool ValidateProgramUniform4uivEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
const GLuint *value)
{
return ValidateProgramUniform4uivBase(context, programPacked, locationPacked, count, value);
}
bool ValidateProgramUniformMatrix2fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix2fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix2x3fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix2x4fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix3fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix3fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix3x2fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix3x4fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix4fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix4fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix4x2fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context,
ShaderProgramID programPacked,
UniformLocation locationPacked,
GLsizei count,
GLboolean transpose,
const GLfloat *value)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateProgramUniformMatrix4x3fvBase(context, programPacked, locationPacked, count,
transpose, value);
}
bool ValidateUseProgramStagesEXT(const Context *context,
ProgramPipelineID pipelinePacked,
GLbitfield stages,
ShaderProgramID programPacked)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateUseProgramStagesBase(context, pipelinePacked, stages, programPacked);
}
bool ValidateValidateProgramPipelineEXT(const Context *context, ProgramPipelineID pipelinePacked)
{
if (!context->getExtensions().separateShaderObjects)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
return ValidateValidateProgramPipelineBase(context, pipelinePacked);
}
// GL_EXT_debug_label
bool ValidateGetObjectLabelEXT(const Context *context,
GLenum type,
GLuint object,
GLsizei bufSize,
const GLsizei *length,
const GLchar *label)
{
if (!context->getExtensions().debugLabel)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
if (bufSize < 0)
{
context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
return false;
}
return ValidateObjectIdentifierAndName(context, type, object);
}
bool ValidateLabelObjectEXT(const Context *context,
GLenum type,
GLuint object,
GLsizei length,
const GLchar *label)
{
if (!context->getExtensions().debugLabel)
{
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
return false;
}
if (length < 0)
{
context->validationError(GL_INVALID_VALUE, kNegativeLength);
return false;
}
return ValidateObjectIdentifierAndName(context, type, object);
}
} // namespace gl