Commit 137032d9 by Martin Radev Committed by Commit Bot

Validate ANGLE_multiview end-points

The patch adds validation for the ANGLE_multiview end-points and propagates the calls to the unimplemented stubs in Context. The patch also removes the glFramebufferTextureMultiviewSideBySideRobustANGLE end-point because the size of the viewport offsets buffer can trivially be computed from the number of views. BUG=angleproject:2062 Change-Id: I9a10bc00c19825e586d3df2750fabea4daf5ef8f Reviewed-on: https://chromium-review.googlesource.com/573861 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 222c517f
...@@ -531,11 +531,9 @@ GL_APICALL void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id, GLenum p ...@@ -531,11 +531,9 @@ GL_APICALL void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id, GLenum p
#define GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE 0x9637 #define GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE 0x9637
typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWLAYEREDANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWLAYEREDANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWSIDEBYSIDEANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets); typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWSIDEBYSIDEANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets);
typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWSIDEBYSIDEROBUSTANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, GLsizei bufSize, const GLint *viewportOffsets);
#ifdef GL_GLEXT_PROTOTYPES #ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewLayeredANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewLayeredANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets); GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets);
GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewSideBySideRobustANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, GLsizei bufSize, const GLint *viewportOffsets);
#endif #endif
#endif /* GL_ANGLE_multiview */ #endif /* GL_ANGLE_multiview */
......
...@@ -2653,6 +2653,8 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions) ...@@ -2653,6 +2653,8 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
mExtensions.colorBufferFloat = false; mExtensions.colorBufferFloat = false;
mExtensions.eglImageExternalEssl3 = false; mExtensions.eglImageExternalEssl3 = false;
mExtensions.textureNorm16 = false; mExtensions.textureNorm16 = false;
mExtensions.multiview = false;
mExtensions.maxViews = 1u;
} }
if (getClientVersion() > Version(2, 0)) if (getClientVersion() > Version(2, 0))
...@@ -3094,6 +3096,26 @@ void Context::framebufferTextureLayer(GLenum target, ...@@ -3094,6 +3096,26 @@ void Context::framebufferTextureLayer(GLenum target,
mGLState.setObjectDirty(target); mGLState.setObjectDirty(target);
} }
void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint baseViewIndex,
GLsizei numViews)
{
UNIMPLEMENTED();
}
void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLsizei numViews,
const GLint *viewportOffsets)
{
UNIMPLEMENTED();
}
void Context::drawBuffers(GLsizei n, const GLenum *bufs) void Context::drawBuffers(GLsizei n, const GLenum *bufs)
{ {
Framebuffer *framebuffer = mGLState.getDrawFramebuffer(); Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
......
...@@ -438,6 +438,18 @@ class Context final : public ValidationContext ...@@ -438,6 +438,18 @@ class Context final : public ValidationContext
GLuint texture, GLuint texture,
GLint level, GLint level,
GLint layer); GLint layer);
void framebufferTextureMultiviewLayeredANGLE(GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint baseViewIndex,
GLsizei numViews);
void framebufferTextureMultiviewSideBySideANGLE(GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLsizei numViews,
const GLint *viewportOffsets);
void drawBuffers(GLsizei n, const GLenum *bufs); void drawBuffers(GLsizei n, const GLenum *bufs);
void readBuffer(GLenum mode); void readBuffer(GLenum mode);
......
...@@ -19,6 +19,7 @@ namespace gl ...@@ -19,6 +19,7 @@ namespace gl
ERRMSG(ActiveTextureRange, "Cannot be less than 0 or greater than maximum number of textures."); ERRMSG(ActiveTextureRange, "Cannot be less than 0 or greater than maximum number of textures.");
ERRMSG(BufferNotBound, "A buffer must be bound."); ERRMSG(BufferNotBound, "A buffer must be bound.");
ERRMSG(ClearInvalidMask, "Invalid mask bits."); ERRMSG(ClearInvalidMask, "Invalid mask bits.");
ERRMSG(CompressedTexturesNotAttachable, "Compressed textures cannot be attached to a framebuffer.");
ERRMSG(CubemapFacesEqualDimensions, "Each cubemap face must have equal width and height."); ERRMSG(CubemapFacesEqualDimensions, "Each cubemap face must have equal width and height.");
ERRMSG(CubemapIncomplete, ERRMSG(CubemapIncomplete,
"Texture is not cubemap complete. All cubemaps faces must be defined and be the same size."); "Texture is not cubemap complete. All cubemaps faces must be defined and be the same size.");
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "common/mathutil.h" #include "common/mathutil.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h"
#include "libANGLE/Framebuffer.h" #include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Renderbuffer.h" #include "libANGLE/Renderbuffer.h"
...@@ -24,6 +25,65 @@ using namespace angle; ...@@ -24,6 +25,65 @@ using namespace angle;
namespace gl namespace gl
{ {
namespace
{
bool ValidateFramebufferTextureMultiviewBaseANGLE(Context *context,
GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLsizei numViews)
{
if (!context->getExtensions().multiview)
{
context->handleError(InvalidOperation() << "ANGLE_multiview is not available.");
return false;
}
if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
{
return false;
}
if (numViews < 1)
{
context->handleError(InvalidValue() << "numViews cannot be less than 1.");
return false;
}
const Extensions &extensions = context->getExtensions();
if (static_cast<GLuint>(numViews) > extensions.maxViews)
{
context->handleError(InvalidValue()
<< "numViews cannot be greater than GL_MAX_VIEWS_ANGLE.");
return false;
}
return true;
}
bool ValidateFramebufferTextureMultiviewLevelAndFormat(Context *context,
Texture *texture,
GLint level)
{
GLenum texTarget = texture->getTarget();
if (!ValidMipLevel(context, texTarget, level))
{
ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
return false;
}
const auto &format = texture->getFormat(texTarget, level);
if (format.info->compressed)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), CompressedTexturesNotAttachable);
return false;
}
return true;
}
} // namespace
static bool ValidateTexImageFormatCombination(gl::Context *context, static bool ValidateTexImageFormatCombination(gl::Context *context,
GLenum target, GLenum target,
GLenum internalFormat, GLenum internalFormat,
...@@ -2571,4 +2631,108 @@ bool ValidateDrawElementsInstanced(ValidationContext *context, ...@@ -2571,4 +2631,108 @@ bool ValidateDrawElementsInstanced(ValidationContext *context,
return ValidateDrawElementsInstancedCommon(context, mode, count, type, indices, instanceCount); return ValidateDrawElementsInstancedCommon(context, mode, count, type, indices, instanceCount);
} }
bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context,
GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint baseViewIndex,
GLsizei numViews)
{
if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
numViews))
{
return false;
}
if (baseViewIndex < 0)
{
context->handleError(InvalidValue() << "baseViewIndex cannot be less than 0.");
return false;
}
if (texture != 0)
{
Texture *tex = context->getTexture(texture);
ASSERT(tex);
switch (tex->getTarget())
{
case GL_TEXTURE_2D_ARRAY:
{
const Caps &caps = context->getCaps();
if (static_cast<GLuint>(baseViewIndex + numViews) > caps.maxArrayTextureLayers)
{
context->handleError(InvalidValue() << "baseViewIndex+numViews cannot be "
"greater than "
"GL_MAX_ARRAY_TEXTURE_LAYERS.");
return false;
}
}
break;
default:
context->handleError(InvalidOperation()
<< "Texture's target must be GL_TEXTURE_2D_ARRAY.");
return false;
}
if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
{
return false;
}
}
return true;
}
bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context,
GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLsizei numViews,
const GLint *viewportOffsets)
{
if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level,
numViews))
{
return false;
}
const GLsizei numViewportOffsetValues = numViews * 2;
for (GLsizei i = 0; i < numViewportOffsetValues; ++i)
{
if (viewportOffsets[i] < 0)
{
context->handleError(InvalidValue()
<< "viewportOffsets cannot contain negative values.");
return false;
}
}
if (texture != 0)
{
Texture *tex = context->getTexture(texture);
ASSERT(tex);
switch (tex->getTarget())
{
case GL_TEXTURE_2D:
break;
default:
context->handleError(InvalidOperation()
<< "Texture's target must be GL_TEXTURE_2D.");
return false;
}
if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level))
{
return false;
}
}
return true;
}
} // namespace gl } // namespace gl
...@@ -427,6 +427,22 @@ bool ValidateDrawElementsInstanced(ValidationContext *context, ...@@ -427,6 +427,22 @@ bool ValidateDrawElementsInstanced(ValidationContext *context,
const void *indices, const void *indices,
GLsizei instanceCount); GLsizei instanceCount);
bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context,
GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint baseViewIndex,
GLsizei numViews);
bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context,
GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLsizei numViews,
const GLint *viewportOffsets);
} // namespace gl } // namespace gl
#endif // LIBANGLE_VALIDATION_ES3_H_ #endif // LIBANGLE_VALIDATION_ES3_H_
...@@ -1634,7 +1634,6 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char * ...@@ -1634,7 +1634,6 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *
// GL_ANGLE_multiview // GL_ANGLE_multiview
INSERT_PROC_ADDRESS(gl, FramebufferTextureMultiviewLayeredANGLE); INSERT_PROC_ADDRESS(gl, FramebufferTextureMultiviewLayeredANGLE);
INSERT_PROC_ADDRESS(gl, FramebufferTextureMultiviewSideBySideANGLE); INSERT_PROC_ADDRESS(gl, FramebufferTextureMultiviewSideBySideANGLE);
INSERT_PROC_ADDRESS(gl, FramebufferTextureMultiviewSideBySideRobustANGLE);
// GLES3 core // GLES3 core
INSERT_PROC_ADDRESS(gl, ReadBuffer); INSERT_PROC_ADDRESS(gl, ReadBuffer);
......
...@@ -3525,7 +3525,18 @@ GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewLayeredANGLE(GLenum targe ...@@ -3525,7 +3525,18 @@ GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewLayeredANGLE(GLenum targe
"(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, " "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, "
"GLint baseViewIndex = %d, GLsizei numViews = %d)", "GLint baseViewIndex = %d, GLsizei numViews = %d)",
target, attachment, texture, level, baseViewIndex, numViews); target, attachment, texture, level, baseViewIndex, numViews);
UNIMPLEMENTED(); Context *context = GetValidGlobalContext();
if (context)
{
if (!context->skipValidation() &&
!ValidateFramebufferTextureMultiviewLayeredANGLE(context, target, attachment, texture,
level, baseViewIndex, numViews))
{
return;
}
context->framebufferTextureMultiviewLayeredANGLE(target, attachment, texture, level,
baseViewIndex, numViews);
}
} }
GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewSideBySideANGLE(GLenum target, GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewSideBySideANGLE(GLenum target,
...@@ -3539,23 +3550,18 @@ GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewSideBySideANGLE(GLenum ta ...@@ -3539,23 +3550,18 @@ GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewSideBySideANGLE(GLenum ta
"(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, " "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, "
"GLsizei numViews = %d, GLsizei* viewportOffsets = 0x%0.8p)", "GLsizei numViews = %d, GLsizei* viewportOffsets = 0x%0.8p)",
target, attachment, texture, level, numViews, viewportOffsets); target, attachment, texture, level, numViews, viewportOffsets);
UNIMPLEMENTED(); Context *context = GetValidGlobalContext();
} if (context)
{
GL_APICALL void GL_APIENTRY if (!context->skipValidation() &&
FramebufferTextureMultiviewSideBySideRobustANGLE(GLenum target, !ValidateFramebufferTextureMultiviewSideBySideANGLE(
GLenum attachment, context, target, attachment, texture, level, numViews, viewportOffsets))
GLuint texture, {
GLint level, return;
GLsizei numViews, }
GLsizei bufSize, context->framebufferTextureMultiviewSideBySideANGLE(target, attachment, texture, level,
const GLint *viewportOffsets) numViews, viewportOffsets);
{ }
EVENT(
"(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, "
"GLsizei numViews = %d, GLsizei bufSize = %d, GLsizei* viewportOffsets = 0x%0.8p)",
target, attachment, texture, level, numViews, viewportOffsets);
UNIMPLEMENTED();
} }
} // gl } // gl
...@@ -712,14 +712,6 @@ FramebufferTextureMultiviewSideBySideANGLE(GLenum target, ...@@ -712,14 +712,6 @@ FramebufferTextureMultiviewSideBySideANGLE(GLenum target,
GLint level, GLint level,
GLsizei numViews, GLsizei numViews,
const GLint *viewportOffsets); const GLint *viewportOffsets);
ANGLE_EXPORT void GL_APIENTRY
FramebufferTextureMultiviewSideBySideRobustANGLE(GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLsizei numViews,
GLsizei bufSize,
const GLint *viewportOffsets);
} // namespace gl } // namespace gl
#endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_ #endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_
...@@ -2567,16 +2567,4 @@ void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum target, ...@@ -2567,16 +2567,4 @@ void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum target,
viewportOffsets); viewportOffsets);
} }
void GL_APIENTRY glFramebufferTextureMultiviewSideBySideRobustANGLE(GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLsizei numViews,
GLsizei bufSize,
const GLint *viewportOffsets)
{
gl::FramebufferTextureMultiviewSideBySideRobustANGLE(target, attachment, texture, level,
numViews, bufSize, viewportOffsets);
}
} // extern "C" } // extern "C"
...@@ -233,7 +233,6 @@ EXPORTS ...@@ -233,7 +233,6 @@ EXPORTS
glFramebufferTextureMultiviewLayeredANGLE @413 glFramebufferTextureMultiviewLayeredANGLE @413
glFramebufferTextureMultiviewSideBySideANGLE @414 glFramebufferTextureMultiviewSideBySideANGLE @414
glFramebufferTextureMultiviewSideBySideRobustANGLE @415
; GLES 3.0 Functions ; GLES 3.0 Functions
glReadBuffer @180 glReadBuffer @180
......
...@@ -14,7 +14,7 @@ using namespace angle; ...@@ -14,7 +14,7 @@ using namespace angle;
class FramebufferMultiviewTest : public ANGLETest class FramebufferMultiviewTest : public ANGLETest
{ {
protected: protected:
FramebufferMultiviewTest() : mFramebuffer(0), mTexture(0) FramebufferMultiviewTest() : mFramebuffer(0), mTexture2D(0), mTexture2DArray(0)
{ {
setWindowWidth(128); setWindowWidth(128);
setWindowHeight(128); setWindowHeight(128);
...@@ -28,21 +28,22 @@ class FramebufferMultiviewTest : public ANGLETest ...@@ -28,21 +28,22 @@ class FramebufferMultiviewTest : public ANGLETest
glGenFramebuffers(1, &mFramebuffer); glGenFramebuffers(1, &mFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA16F, 1, 1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
glRequestExtensionANGLE = reinterpret_cast<PFNGLREQUESTEXTENSIONANGLEPROC>( glRequestExtensionANGLE = reinterpret_cast<PFNGLREQUESTEXTENSIONANGLEPROC>(
eglGetProcAddress("glRequestExtensionANGLE")); eglGetProcAddress("glRequestExtensionANGLE"));
} }
void TearDown() override void TearDown() override
{ {
if (mTexture != 0) if (mTexture2D != 0)
{
glDeleteTextures(1, &mTexture2D);
mTexture2D = 0;
}
if (mTexture2DArray != 0)
{ {
glDeleteTextures(1, &mTexture); glDeleteTextures(1, &mTexture2DArray);
mTexture = 0; mTexture2DArray = 0;
} }
if (mFramebuffer != 0) if (mFramebuffer != 0)
...@@ -54,8 +55,41 @@ class FramebufferMultiviewTest : public ANGLETest ...@@ -54,8 +55,41 @@ class FramebufferMultiviewTest : public ANGLETest
ANGLETest::TearDown(); ANGLETest::TearDown();
} }
void createTexture2D()
{
glGenTextures(1, &mTexture2D);
glBindTexture(GL_TEXTURE_2D, mTexture2D);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA16F, 1, 1);
ASSERT_GL_NO_ERROR();
}
void createTexture2DArray()
{
glGenTextures(1, &mTexture2DArray);
glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture2DArray);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA16F, 1, 1, 2);
ASSERT_GL_NO_ERROR();
}
// Requests the ANGLE_multiview extension and returns true if the operation succeeds.
bool requestMultiviewExtension()
{
if (extensionRequestable("GL_ANGLE_multiview"))
{
glRequestExtensionANGLE("GL_ANGLE_multiview");
}
if (!extensionEnabled("GL_ANGLE_multiview"))
{
std::cout << "Test skipped due to missing GL_ANGLE_multiview." << std::endl;
return false;
}
return true;
}
GLuint mFramebuffer; GLuint mFramebuffer;
GLuint mTexture; GLuint mTexture2D;
GLuint mTexture2DArray;
PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr; PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr;
}; };
...@@ -63,17 +97,14 @@ class FramebufferMultiviewTest : public ANGLETest ...@@ -63,17 +97,14 @@ class FramebufferMultiviewTest : public ANGLETest
// state and that their corresponding default values are correctly set. // state and that their corresponding default values are correctly set.
TEST_P(FramebufferMultiviewTest, DefaultState) TEST_P(FramebufferMultiviewTest, DefaultState)
{ {
if (extensionRequestable("GL_ANGLE_multiview")) if (!requestMultiviewExtension())
{
glRequestExtensionANGLE("GL_ANGLE_multiview");
}
if (!extensionEnabled("GL_ANGLE_multiview"))
{ {
std::cout << "Test skipped due to missing GL_ANGLE_multiview." << std::endl;
return; return;
} }
createTexture2D();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
GLint numViews = -1; GLint numViews = -1;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
...@@ -108,6 +139,9 @@ TEST_P(FramebufferMultiviewTest, DefaultState) ...@@ -108,6 +139,9 @@ TEST_P(FramebufferMultiviewTest, DefaultState)
// the ANGLE_multiview tokens results in an INVALID_ENUM error. // the ANGLE_multiview tokens results in an INVALID_ENUM error.
TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries) TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries)
{ {
createTexture2D();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
GLint numViews = -1; GLint numViews = -1;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE,
...@@ -133,4 +167,63 @@ TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries) ...@@ -133,4 +167,63 @@ TEST_P(FramebufferMultiviewTest, NegativeFramebufferStateQueries)
EXPECT_GL_ERROR(GL_INVALID_ENUM); EXPECT_GL_ERROR(GL_INVALID_ENUM);
} }
// Test that the correct errors are generated whenever glFramebufferTextureMultiviewSideBySideANGLE
// is called with invalid arguments.
TEST_P(FramebufferMultiviewTest, InvalidMultiviewSideBySideArguments)
{
if (!requestMultiviewExtension())
{
return;
}
createTexture2D();
// Negative offsets.
int viewportOffsets[2] = {-1};
glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
0, 1, &viewportOffsets[0]);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// Negative number of views.
viewportOffsets[0] = 0;
viewportOffsets[1] = 0;
glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
0, -1, &viewportOffsets[0]);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Test that the correct errors are generated whenever glFramebufferTextureMultiviewLayeredANGLE is
// called with invalid arguments.
TEST_P(FramebufferMultiviewTest, InvalidMultiviewLayeredArguments)
{
if (!requestMultiviewExtension())
{
return;
}
createTexture2DArray();
// Negative base view index.
glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
0, -1, 1);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// baseViewIndex + numViews is greater than MAX_TEXTURE_LAYERS.
GLint maxTextureLayers = 0;
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureLayers);
ASSERT_GL_NO_ERROR();
glFramebufferTextureMultiviewLayeredANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2DArray,
0, maxTextureLayers, 1);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Test that an INVALID_OPERATION error is generated whenever the ANGLE_multiview extension is not
// available.
TEST_P(FramebufferMultiviewTest, ExtensionNotAvailableCheck)
{
createTexture2D();
int viewportOffsets[2] = {0};
glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
0, 1, &viewportOffsets[0]);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL());
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment