ES31: Implement multisampled Textures.
Implement TexStorage2DMultisample and getMultisamplefv entry point.
Also modify sample state for Textures and Framebuffers.
BUG=angleproject:1590
TEST=angle_unittests
TEST=angle_end2end_tests
TEST=dEQP-GLES31.functional.texture.multisample.samples_*.sample_position
TEST=dEQP-GLES31.functional.texture.multisample.samples_*.use_texture_color_2d
TEST=dEQP-GLES31.functional.texture.multisample.samples_*.use_texture_depth_2d
TEST=dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_different_sample_count_tex_tex
TEST=dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_different_sample_count_tex_rbo
TEST=dEQP-GLES31.functional.texture.multisample.negative.fbo_attach_non_zero_level
TEST=dEQP-GLES31.functional.texture.multisample.negative.texture_high_sample_count
TEST=dEQP-GLES31.functional.texture.multisample.negative.texture_zero_sample_count
TEST=dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_1_texture_2d
TEST=dEQP-GLES31.functional.shaders.builtin_functions.texture_size.samples_4_texture_2d
Change-Id: I8fa7bd4e73b95745858a3e16b1b92004b4a18712
Reviewed-on: https://chromium-review.googlesource.com/414309
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/validationES31.cpp b/src/libANGLE/validationES31.cpp
index 39ee404..3854fbb 100644
--- a/src/libANGLE/validationES31.cpp
+++ b/src/libANGLE/validationES31.cpp
@@ -274,4 +274,118 @@
return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
}
+bool ValidateTexStorage2DMultiSample(Context *context,
+ GLenum target,
+ GLsizei samples,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.1."));
+ return false;
+ }
+
+ if (target != GL_TEXTURE_2D_MULTISAMPLE)
+ {
+ context->handleError(Error(GL_INVALID_ENUM, "Target must be TEXTURE_2D_MULTISAMPLE."));
+ return false;
+ }
+
+ if (width < 1 || height < 1)
+ {
+ context->handleError(Error(GL_INVALID_VALUE, "Width and height must be positive."));
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
+ static_cast<GLuint>(height) > caps.max2DTextureSize)
+ {
+ context->handleError(
+ Error(GL_INVALID_VALUE,
+ "Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE."));
+ return false;
+ }
+
+ if (samples == 0)
+ {
+ context->handleError(Error(GL_INVALID_VALUE, "Samples may not be zero."));
+ return false;
+ }
+
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
+ if (!formatCaps.renderable)
+ {
+ context->handleError(
+ Error(GL_INVALID_ENUM,
+ "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 gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+ if (formatInfo.pixelBytes == 0)
+ {
+ context->handleError(
+ Error(GL_INVALID_ENUM,
+ "Internalformat is one of the unsupported unsized base internalformats."));
+ return false;
+ }
+
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
+ {
+ context->handleError(
+ Error(GL_INVALID_OPERATION,
+ "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(Error(GL_INVALID_OPERATION, "Zero is bound to target."));
+ return false;
+ }
+
+ if (texture->getImmutableFormat())
+ {
+ context->handleError(
+ Error(GL_INVALID_OPERATION,
+ "The value of TEXTURE_IMMUTABLE_FORMAT for the texture "
+ "currently bound to target on the active texture unit is true."));
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.1."));
+ return false;
+ }
+
+ if (pname != GL_SAMPLE_POSITION)
+ {
+ context->handleError(Error(GL_INVALID_ENUM, "Pname must be SAMPLE_POSITION."));
+ return false;
+ }
+
+ GLint maxSamples = context->getCaps().maxSamples;
+ if (index >= static_cast<GLuint>(maxSamples))
+ {
+ context->handleError(
+ Error(GL_INVALID_VALUE, "Index must be less than the value of SAMPLES."));
+ return false;
+ }
+
+ return true;
+}
} // namespace gl