Commit d310a434 by Olli Etuaho Committed by Commit Bot

Add validation and negative tests for multisample arrays

This adds errors for binding and allocating multisample array textures. New tests in TextureMultisampleTest.cpp check that the errors are generated as specified. Tests for querying supported sample counts are also improved and extended for multisample array textures. BUG=angleproject:2775 TEST=angle_end2end_tests Change-Id: I6a0fe7ae04bb3d0072f6cbe09026b05e2bc47325 Reviewed-on: https://chromium-review.googlesource.com/1188576 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 1e1b731a
......@@ -88,7 +88,7 @@
"packed enum:src/common/packed_egl_enums.json":
"0389a8a565ccee99163bd0cf3ca146d3",
"packed enum:src/common/packed_gl_enums.json":
"8b60e7bae297eba956166422824d639c",
"522c7f55be07b2e56364766be9b1cc04",
"proc table:src/libGLESv2/gen_proc_table.py":
"027bfd5a8a8dffe91f492bf199029cde",
"proc table:src/libGLESv2/proc_table_data.json":
......
......@@ -34,6 +34,8 @@ TextureType TextureTargetToType(TextureTarget target)
return TextureType::_2DArray;
case TextureTarget::_2DMultisample:
return TextureType::_2DMultisample;
case TextureTarget::_2DMultisampleArray:
return TextureType::_2DMultisampleArray;
case TextureTarget::_3D:
return TextureType::_3D;
default:
......@@ -61,6 +63,8 @@ TextureTarget NonCubeTextureTypeToTarget(TextureType type)
return TextureTarget::_2DArray;
case TextureType::_2DMultisample:
return TextureTarget::_2DMultisample;
case TextureType::_2DMultisampleArray:
return TextureTarget::_2DMultisampleArray;
case TextureType::_3D:
return TextureTarget::_3D;
default:
......
......@@ -1066,6 +1066,8 @@ TextureTarget FromGLenum<TextureTarget>(GLenum from)
return TextureTarget::_2DArray;
case GL_TEXTURE_2D_MULTISAMPLE:
return TextureTarget::_2DMultisample;
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE:
return TextureTarget::_2DMultisampleArray;
case GL_TEXTURE_3D:
return TextureTarget::_3D;
case GL_TEXTURE_EXTERNAL_OES:
......@@ -1099,6 +1101,8 @@ GLenum ToGLenum(TextureTarget from)
return GL_TEXTURE_2D_ARRAY;
case TextureTarget::_2DMultisample:
return GL_TEXTURE_2D_MULTISAMPLE;
case TextureTarget::_2DMultisampleArray:
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE;
case TextureTarget::_3D:
return GL_TEXTURE_3D;
case TextureTarget::External:
......@@ -1134,6 +1138,8 @@ TextureType FromGLenum<TextureType>(GLenum from)
return TextureType::_2DArray;
case GL_TEXTURE_2D_MULTISAMPLE:
return TextureType::_2DMultisample;
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE:
return TextureType::_2DMultisampleArray;
case GL_TEXTURE_3D:
return TextureType::_3D;
case GL_TEXTURE_EXTERNAL_OES:
......@@ -1157,6 +1163,8 @@ GLenum ToGLenum(TextureType from)
return GL_TEXTURE_2D_ARRAY;
case TextureType::_2DMultisample:
return GL_TEXTURE_2D_MULTISAMPLE;
case TextureType::_2DMultisampleArray:
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE;
case TextureType::_3D:
return GL_TEXTURE_3D;
case TextureType::External:
......
......@@ -418,21 +418,22 @@ GLenum ToGLenum(TextureSrc from);
enum class TextureTarget : uint8_t
{
_2D = 0,
_2DArray = 1,
_2DMultisample = 2,
_3D = 3,
External = 4,
Rectangle = 5,
CubeMapPositiveX = 6,
CubeMapNegativeX = 7,
CubeMapPositiveY = 8,
CubeMapNegativeY = 9,
CubeMapPositiveZ = 10,
CubeMapNegativeZ = 11,
InvalidEnum = 12,
EnumCount = 12,
_2D = 0,
_2DArray = 1,
_2DMultisample = 2,
_2DMultisampleArray = 3,
_3D = 4,
External = 5,
Rectangle = 6,
CubeMapPositiveX = 7,
CubeMapNegativeX = 8,
CubeMapPositiveY = 9,
CubeMapNegativeY = 10,
CubeMapPositiveZ = 11,
CubeMapNegativeZ = 12,
InvalidEnum = 13,
EnumCount = 13,
};
template <>
......@@ -441,16 +442,17 @@ GLenum ToGLenum(TextureTarget from);
enum class TextureType : uint8_t
{
_2D = 0,
_2DArray = 1,
_2DMultisample = 2,
_3D = 3,
External = 4,
Rectangle = 5,
CubeMap = 6,
_2D = 0,
_2DArray = 1,
_2DMultisample = 2,
_2DMultisampleArray = 3,
_3D = 4,
External = 5,
Rectangle = 6,
CubeMap = 7,
InvalidEnum = 7,
EnumCount = 7,
InvalidEnum = 8,
EnumCount = 8,
};
template <>
......
......@@ -176,6 +176,7 @@
"_2D": "GL_TEXTURE_2D",
"_2DArray": "GL_TEXTURE_2D_ARRAY",
"_2DMultisample": "GL_TEXTURE_2D_MULTISAMPLE",
"_2DMultisampleArray": "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE",
"_3D": "GL_TEXTURE_3D",
"External": "GL_TEXTURE_EXTERNAL_OES",
"Rectangle": "GL_TEXTURE_RECTANGLE_ANGLE",
......@@ -186,6 +187,7 @@
"_2D": "GL_TEXTURE_2D",
"_2DArray": "GL_TEXTURE_2D_ARRAY",
"_2DMultisample": "GL_TEXTURE_2D_MULTISAMPLE",
"_2DMultisampleArray": "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE",
"_3D": "GL_TEXTURE_3D",
"External": "GL_TEXTURE_EXTERNAL_OES",
"Rectangle": "GL_TEXTURE_RECTANGLE_ANGLE",
......
......@@ -249,7 +249,8 @@ Extensions::Extensions()
drawTexture(false),
explicitContextGles1(false),
explicitContext(false),
parallelShaderCompile(false)
parallelShaderCompile(false),
textureMultisampleArray(false)
{
}
......@@ -854,6 +855,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_ANGLE_explicit_context_gles1"] = enableableExtension(&Extensions::explicitContextGles1);
map["GL_ANGLE_explicit_context"] = enableableExtension(&Extensions::explicitContext);
map["GL_KHR_parallel_shader_compile"] = enableableExtension(&Extensions::parallelShaderCompile);
map["GL_ANGLE_texture_multisample_array"] = enableableExtension(&Extensions::textureMultisampleArray);
// GLES1 extensinos
map["GL_OES_point_size_array"] = enableableExtension(&Extensions::pointSizeArray);
map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMap);
......
......@@ -426,6 +426,9 @@ struct Extensions
// GL_KHR_parallel_shader_compile
bool parallelShaderCompile;
// GL_ANGLE_texture_multisample_array
bool textureMultisampleArray;
};
struct ExtensionInfo
......
......@@ -411,9 +411,13 @@ void Context::initialize()
}
if (getClientVersion() >= Version(3, 1))
{
// TODO(http://anglebug.com/2775): These could also be enabled via extension
Texture *zeroTexture2DMultisample =
new Texture(mImplementation.get(), 0, TextureType::_2DMultisample);
mZeroTextures[TextureType::_2DMultisample].set(this, zeroTexture2DMultisample);
Texture *zeroTexture2DMultisampleArray =
new Texture(mImplementation.get(), 0, TextureType::_2DMultisampleArray);
mZeroTextures[TextureType::_2DMultisampleArray].set(this, zeroTexture2DMultisampleArray);
for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
{
......@@ -3152,6 +3156,10 @@ Extensions Context::generateSupportedExtensions() const
{
// Disable ES3.1+ extensions
supportedExtensions.geometryShader = false;
// TODO(http://anglebug.com/2775): Multisample arrays could be supported on ES 3.0 as well
// once 2D multisample texture extension is exposed there.
supportedExtensions.textureMultisampleArray = false;
}
if (getClientVersion() > ES_2_0)
......
......@@ -102,6 +102,9 @@ ERRMSG(FramebufferIncompleteAttachment,
ERRMSG(GenerateMipmapNotAllowed, "Texture format does not support mipmap generation.");
ERRMSG(GeometryShaderExtensionNotEnabled, "GL_EXT_geometry_shader extension not enabled.");
ERRMSG(GLES1Only, "GLES1-only function.");
ERRMSG(ImmutableTextureBound,
"The value of TEXTURE_IMMUTABLE_FORMAT for the texture currently bound to target on the "
"active texture unit is true.");
ERRMSG(IncompatibleDrawModeAgainstGeometryShader,
"Primitive mode is incompatible with the input primitive type of the geometry shader.");
ERRMSG(IndexExceedsMaxActiveUniform, "Index exceeds program active uniform count.");
......@@ -238,6 +241,7 @@ ERRMSG(MultiviewTimerQuery,
"There is an active query for target "
"GL_TIME_ELAPSED_EXT when the number of views in the "
"active draw framebuffer is greater than 1.");
ERRMSG(MultisampleArrayExtensionRequired, "GL_ANGLE_texture_multisample_array not enabled.");
ERRMSG(NameBeginsWithGL, "Attributes that begin with 'gl_' are not allowed.");
ERRMSG(NegativeAttachments, "Negative number of attachments.");
ERRMSG(NegativeBufferSize, "Negative buffer size.");
......@@ -282,8 +286,13 @@ ERRMSG(ProgramNotLinked, "Program not linked.");
ERRMSG(QueryActive, "Query is active.");
ERRMSG(QueryExtensionNotEnabled, "Query extension not enabled.");
ERRMSG(ReadBufferNone, "Read buffer is GL_NONE.");
ERRMSG(RenderableInternalFormat,
"SizedInternalformat must be color-renderable, depth-renderable, or stencil-renderable.");
ERRMSG(RenderbufferNotBound, "A renderbuffer must be bound.");
ERRMSG(ResourceMaxTextureSize, "Desired resource size is greater than max texture size.");
ERRMSG(SamplesZero, "Samples may not be zero.");
ERRMSG(SamplesOutOfRange,
"Samples must not be greater than maximum supported value for the format.");
ERRMSG(ShaderAttachmentHasShader, "Shader attachment already has a shader.");
ERRMSG(ShaderSourceInvalidCharacters, "Shader source contains invalid characters.");
ERRMSG(ShaderToDetachMustBeAttached,
......@@ -293,9 +302,14 @@ ERRMSG(StencilReferenceMaskOrMismatch,
"Stencil reference and mask values must be the same for front facing and back facing "
"triangles.");
ERRMSG(StrideMustBeMultipleOfType, "Stride must be a multiple of the passed in datatype.");
ERRMSG(TargetMustBeTexture2DMultisampleArrayANGLE,
"Target must be TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE.");
ERRMSG(TextureNotBound, "A texture must be bound.");
ERRMSG(TextureNotPow2, "The texture is a non-power-of-two texture.");
ERRMSG(TextureTargetRequiresES31, "Texture target requires at least OpenGL ES 3.1.");
ERRMSG(TextureTypeConflict, "Two textures of different types use the same sampler location.");
ERRMSG(TextureWidthOrHeightOutOfRange,
"Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE.");
ERRMSG(TransformFeedbackBufferDoubleBound,
"A transform feedback buffer that would be written to is also bound to a "
"non-transform-feedback target, which would cause undefined behavior.");
......@@ -313,6 +327,8 @@ ERRMSG(UniformBufferUnbound,
"It is undefined behaviour to have a used but unbound uniform buffer.");
ERRMSG(UniformSizeMismatch, "Uniform size does not match uniform method.");
ERRMSG(UnknownParameter, "Unknown parameter value.");
ERRMSG(UnsizedInternalFormatUnsupported,
"Internalformat is one of the unsupported unsized base internalformats.");
ERRMSG(UnsupportedDrawModeForTransformFeedback,
"The draw command is unsupported when transform feedback is active and not paused.");
ERRMSG(VertexArrayNoBuffer, "An enabled vertex array has no buffer.");
......@@ -327,6 +343,7 @@ ERRMSG(WebglBindAttribLocationReservedPrefix,
"Attributes that begin with 'webgl_', or '_webgl_' are not allowed.");
ERRMSG(WebglNameLengthLimitExceeded,
"Location name lengths must not be greater than 256 characters.");
ERRMSG(ZeroBoundToTarget, "Zero is bound to target.");
}
#undef ERRMSG
#endif // LIBANGLE_ERRORSTRINGS_H_
......@@ -224,7 +224,10 @@ void State::initialize(Context *context)
}
if (clientVersion >= Version(3, 1))
{
// TODO(http://anglebug.com/2775): These could also be enabled via extension
mSamplerTextures[TextureType::_2DMultisample].resize(caps.maxCombinedTextureImageUnits);
mSamplerTextures[TextureType::_2DMultisampleArray].resize(
caps.maxCombinedTextureImageUnits);
mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
......
......@@ -169,6 +169,11 @@ TextureImpl *Context11::createTexture(const gl::TextureState &state)
return new TextureD3D_External(state, mRenderer);
case gl::TextureType::_2DMultisample:
return new TextureD3D_2DMultisample(state, mRenderer);
case gl::TextureType::_2DMultisampleArray:
// TODO(http://anglebug.com/2775): Proper implementation of D3D multisample array
// textures. Right now multisample array textures are not supported but we need to
// create some object so we don't end up with asserts when using the zero texture array.
return new TextureD3D_2DMultisample(state, mRenderer);
default:
UNREACHABLE();
}
......
......@@ -983,6 +983,11 @@ void GenerateCaps(const FunctionsGL *functions,
extensions->copyTexture = true;
extensions->syncQuery = SyncQueryGL::IsSupported(functions);
// Note that ANGLE_texture_multisample_array support could be extended down to GL 3.2 if we
// emulated texStorage* API on top of texImage*.
extensions->textureMultisampleArray =
functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 2));
// NV_path_rendering
// We also need interface query which is available in
// >= 4.3 core or ARB_interface_query or >= GLES 3.1
......
......@@ -500,6 +500,8 @@ bool ValidTextureTarget(const Context *context, TextureType type)
case TextureType::_2DMultisample:
return (context->getClientVersion() >= Version(3, 1));
case TextureType::_2DMultisampleArray:
return context->getExtensions().textureMultisampleArray;
default:
return false;
......@@ -688,6 +690,8 @@ bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
return true;
case TextureType::Rectangle:
return context->getExtensions().textureRectangle;
case TextureType::_2DMultisampleArray:
return context->getExtensions().textureMultisampleArray;
default:
return false;
}
......@@ -723,6 +727,9 @@ bool ValidMipLevel(const Context *context, TextureType type, GLint level)
case TextureType::_2D:
case TextureType::_2DArray:
case TextureType::_2DMultisample:
case TextureType::_2DMultisampleArray:
// TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
// level-of-detail" for multisample textures should be. Could maybe make it zero.
maxDimension = caps.max2DTextureSize;
break;
case TextureType::CubeMap:
......@@ -2186,6 +2193,13 @@ bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsi
case GL_TEXTURE_BINDING_2D_ARRAY:
case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
break;
case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
if (!context->getExtensions().textureMultisampleArray)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
return false;
}
break;
case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
if (!context->getExtensions().textureRectangle)
{
......@@ -5849,7 +5863,7 @@ bool ValidateTexParameterBase(Context *context,
break;
}
if (target == TextureType::_2DMultisample)
if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
{
switch (pname)
{
......@@ -5982,7 +5996,9 @@ bool ValidateTexParameterBase(Context *context,
<< "Base level must be 0 for external textures.");
return false;
}
if (target == TextureType::_2DMultisample && static_cast<GLuint>(params[0]) != 0)
if ((target == TextureType::_2DMultisample ||
target == TextureType::_2DMultisampleArray) &&
static_cast<GLuint>(params[0]) != 0)
{
context->handleError(InvalidOperation()
<< "Base level must be 0 for multisampled textures.");
......@@ -6315,12 +6331,17 @@ bool ValidateGetInternalFormativBase(Context *context,
case GL_TEXTURE_2D_MULTISAMPLE:
if (context->getClientVersion() < ES_3_1)
{
context->handleError(InvalidOperation()
<< "Texture target requires at least OpenGL ES 3.1.");
ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureTargetRequiresES31);
return false;
}
break;
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE:
if (!context->getExtensions().textureMultisampleArray)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
return false;
}
break;
default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTarget);
return false;
......@@ -6377,4 +6398,62 @@ bool ValidateMultitextureUnit(Context *context, GLenum texture)
return true;
}
bool ValidateTexStorageMultisample(Context *context,
TextureType target,
GLsizei samples,
GLint internalFormat,
GLsizei width,
GLsizei height)
{
const Caps &caps = context->getCaps();
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize)
{
ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureWidthOrHeightOutOfRange);
return false;
}
if (samples == 0)
{
ANGLE_VALIDATION_ERR(context, InvalidValue(), SamplesZero);
return false;
}
const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
if (!formatCaps.textureAttachment)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), RenderableInternalFormat);
return false;
}
// The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
// is one of the unsized base internalformats listed in table 8.11.
const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
if (formatInfo.internalFormat == GL_NONE)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnsizedInternalFormatUnsupported);
return false;
}
if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), SamplesOutOfRange);
return false;
}
Texture *texture = context->getTargetTexture(target);
if (!texture || texture->id() == 0)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ZeroBoundToTarget);
return false;
}
if (texture->getImmutableFormat())
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ImmutableTextureBound);
return false;
}
return true;
}
} // namespace gl
......@@ -683,6 +683,14 @@ bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
PrimitiveMode transformFeedbackPrimitiveMode,
PrimitiveMode renderPrimitiveMode);
// Common validation for 2D and 3D variants of TexStorage*Multisample.
bool ValidateTexStorageMultisample(Context *context,
TextureType target,
GLsizei samples,
GLint internalFormat,
GLsizei width,
GLsizei height);
// Utility macro for handling implementation methods inside Validation.
#define ANGLE_HANDLE_VALIDATION_ERR(X) \
context->handleError(X); \
......
......@@ -3026,7 +3026,13 @@ bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
return false;
}
break;
case TextureType::_2DMultisampleArray:
if (!context->getExtensions().textureMultisampleArray)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
return false;
}
break;
case TextureType::External:
if (!context->getExtensions().eglImageExternal &&
!context->getExtensions().eglStreamConsumerExternal)
......
......@@ -1025,65 +1025,7 @@ bool ValidateTexStorage2DMultisample(Context *context,
return false;
}
const Caps &caps = context->getCaps();
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize)
{
context
->handleError(InvalidValue()
<< "Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE.");
return false;
}
if (samples == 0)
{
context->handleError(InvalidValue() << "Samples may not be zero.");
return false;
}
const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
if (!formatCaps.textureAttachment)
{
context->handleError(InvalidEnum() << "SizedInternalformat must be color-renderable, "
"depth-renderable, or stencil-renderable.");
return false;
}
// The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
// is one of the unsized base internalformats listed in table 8.11.
const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
if (formatInfo.internalFormat == GL_NONE)
{
context->handleError(
InvalidEnum()
<< "Internalformat is one of the unsupported unsized base internalformats.");
return false;
}
if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
{
context->handleError(
InvalidOperation()
<< "Samples must not be greater than maximum supported value for the format.");
return false;
}
Texture *texture = context->getTargetTexture(target);
if (!texture || texture->id() == 0)
{
context->handleError(InvalidOperation() << "Zero is bound to target.");
return false;
}
if (texture->getImmutableFormat())
{
context->handleError(InvalidOperation() << "The value of TEXTURE_IMMUTABLE_FORMAT for "
"the texture currently bound to target on "
"the active texture unit is true.");
return false;
}
return true;
return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
}
bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
......@@ -2022,8 +1964,26 @@ bool ValidateTexStorage3DMultisampleANGLE(Context *context,
GLsizei depth,
GLboolean fixedsamplelocations)
{
UNIMPLEMENTED();
return false;
if (!context->getExtensions().textureMultisampleArray)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
return false;
}
if (target != TextureType::_2DMultisampleArray)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), TargetMustBeTexture2DMultisampleArrayANGLE);
return false;
}
if (width < 1 || height < 1 || depth < 1)
{
ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
return false;
}
return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
height);
}
} // namespace gl
......@@ -70,19 +70,56 @@ class TextureMultisampleTestES31 : public TextureMultisampleTest
TextureMultisampleTestES31() : TextureMultisampleTest() {}
};
class TextureMultisampleArrayWebGLTest : public TextureMultisampleTest
{
protected:
TextureMultisampleArrayWebGLTest() : TextureMultisampleTest()
{
// These tests run in WebGL mode so we can test with both extension off and on.
setWebGLCompatibilityEnabled(true);
}
// Requests the ANGLE_texture_multisample_array extension and returns true if the operation
// succeeds.
bool requestArrayExtension()
{
if (extensionRequestable("GL_ANGLE_texture_multisample_array"))
{
glRequestExtensionANGLE("GL_ANGLE_texture_multisample_array");
}
if (!extensionEnabled("GL_ANGLE_texture_multisample_array"))
{
return false;
}
return true;
}
};
// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
// GetInternalformativ.
// GetInternalformativ. Checks that the number of samples returned is valid in case of ES >= 3.1.
TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase)
{
GLint maxSamples = 0;
glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
// This query returns supported sample counts in descending order. If only one sample count is
// queried, it should be the maximum one.
GLint maxSamplesR8 = 0;
glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamplesR8);
if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
{
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
ASSERT_GL_ERROR(GL_INVALID_ENUM);
}
else
{
ASSERT_GL_NO_ERROR();
// GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
GLint maxColorTextureSamples;
glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
GLint maxSamples;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
GLint maxSamplesR8Required = std::min(maxColorTextureSamples, maxSamples);
EXPECT_GE(maxSamplesR8, maxSamplesR8Required);
}
}
......@@ -217,6 +254,132 @@ TEST_P(TextureMultisampleTestES31, CheckSamplePositions)
ASSERT_GL_NO_ERROR();
}
// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is not supported in GetInternalformativ when the
// extension is not supported.
TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativWithoutExtension)
{
GLint maxSamples = 0;
glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_RGBA8, GL_SAMPLES, 1,
&maxSamples);
ASSERT_GL_ERROR(GL_INVALID_ENUM);
}
// Attempt to bind a texture to multisample array binding point when extension is not supported.
TEST_P(TextureMultisampleArrayWebGLTest, BindMultisampleArrayTextureWithoutExtension)
{
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
ASSERT_GL_ERROR(GL_INVALID_ENUM);
}
// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is supported in GetInternalformativ.
TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativ)
{
ANGLE_SKIP_TEST_IF(!requestArrayExtension());
// This query returns supported sample counts in descending order. If only one sample count is
// queried, it should be the maximum one.
GLint maxSamplesRGBA8 = 0;
glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_RGBA8, GL_SAMPLES, 1,
&maxSamplesRGBA8);
ASSERT_GL_NO_ERROR();
// GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
GLint maxColorTextureSamples;
glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
GLint maxSamples;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
GLint maxSamplesRGBA8Required = std::min(maxColorTextureSamples, maxSamples);
EXPECT_GE(maxSamplesRGBA8, maxSamplesRGBA8Required);
}
// Tests that TexImage3D call cannot be used for GL_TEXTURE_2D_MULTISAMPLE_ARRAY.
TEST_P(TextureMultisampleArrayWebGLTest, MultiSampleArrayTexImage)
{
ANGLE_SKIP_TEST_IF(!requestArrayExtension());
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
ASSERT_GL_NO_ERROR();
glTexImage3D(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
// Tests passing invalid parameters to TexStorage3DMultisample.
TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexStorage3DMultisample)
{
ANGLE_SKIP_TEST_IF(!requestArrayExtension());
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
ASSERT_GL_NO_ERROR();
// Invalid target
glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, 1, GL_TRUE);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
// Samples 0
glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 0, GL_RGBA8, 1, 1, 1,
GL_TRUE);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// Unsized internalformat
glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA, 1, 1, 1,
GL_TRUE);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
// Width 0
glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA8, 0, 1, 1,
GL_TRUE);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// Height 0
glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA8, 1, 0, 1,
GL_TRUE);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// Depth 0
glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA8, 1, 1, 0,
GL_TRUE);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Tests passing invalid parameters to TexParameteri.
TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexParameteri)
{
ANGLE_SKIP_TEST_IF(!requestArrayExtension());
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
ASSERT_GL_NO_ERROR();
// None of the sampler parameters can be set on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE.
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MIN_LOD, 0);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MAX_LOD, 0);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_COMPARE_MODE, GL_NONE);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
// Only valid base level on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE is 0.
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_BASE_LEVEL, 1);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
ES31_D3D11(),
ES3_OPENGL(),
......@@ -224,4 +387,9 @@ ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
ES31_OPENGL(),
ES31_OPENGLES());
ANGLE_INSTANTIATE_TEST(TextureMultisampleTestES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
}
ANGLE_INSTANTIATE_TEST(TextureMultisampleArrayWebGLTest,
ES31_D3D11(),
ES31_OPENGL(),
ES31_OPENGLES());
} // anonymous namespace
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