Commit 536eca10 by Geoff Lang Committed by Commit Bot

Simplify GenerateMipmap validation now that sized format info is tracked.

The previous validation used some workarounds because it didn't know if the texture format was sized or not. Now that the InternalFormat struct tracks this, the validation can work correctly for floating point formats. BUG=angleproject:2149 Change-Id: I583db4a36137a57dd1b7fc81cd4e3b6d5972fc67 Reviewed-on: https://chromium-review.googlesource.com/665163 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 682efdc4
......@@ -37,7 +37,7 @@ ERRMSG(ExtensionNotEnabled, "Extension is not enabled.");
ERRMSG(FeedbackLoop, "Feedback loop formed between Framebuffer and active Texture.");
ERRMSG(FramebufferIncompleteAttachment,
"Attachment type must be compatible with attachment object.");
ERRMSG(GenerateMipmapNotAllowed, "Compressed textures do not support mipmap generation.");
ERRMSG(GenerateMipmapNotAllowed, "Texture format does not support mipmap generation.");
ERRMSG(IndexExceedsMaxActiveUniform, "Index exceeds program active uniform count.");
ERRMSG(IndexExceedsMaxDrawBuffer, "Index exceeds MAX_DRAW_BUFFERS.");
ERRMSG(IndexExceedsMaxVertexAttribute, "Index exceeds MAX_VERTEX_ATTRIBS.");
......
......@@ -6059,37 +6059,40 @@ bool ValidateGenerateMipmap(Context *context, GLenum target)
}
GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
const auto &format = texture->getFormat(baseTarget, effectiveBaseLevel);
const TextureCaps &formatCaps = context->getTextureCaps().get(format.info->sizedInternalFormat);
const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
format.stencilBits > 0)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
return false;
}
if (format.info->compressed)
// GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
bool formatUnsized = !format.sized;
bool formatColorRenderableAndFilterable =
format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
format.renderSupport(context->getClientVersion(), context->getExtensions());
if (!formatUnsized && !formatColorRenderableAndFilterable)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
return false;
}
// GenerateMipmap should not generate an INVALID_OPERATION for textures created with
// unsized formats or that are color renderable and filterable. Since we do not track if
// the texture was created with sized or unsized format (only sized formats are stored),
// it is not possible to make sure the the LUMA formats can generate mipmaps (they should
// be able to) because they aren't color renderable. Simply do a special case for LUMA
// textures since they're the only texture format that can be created with unsized formats
// that is not color renderable. New unsized formats are unlikely to be added, since ES2
// was the last version to use add them.
if (format.info->depthBits > 0 || format.info->stencilBits > 0 || !formatCaps.filterable ||
(!formatCaps.renderable && !format.info->isLUMA()))
// GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
// generation
if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
{
context->handleError(InvalidOperation());
ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
return false;
}
// ES3 and WebGL grant mipmap generation for sRGB textures but GL_EXT_sRGB does not.
// ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
// not.
bool supportsSRGBMipmapGeneration =
context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
if (!supportsSRGBMipmapGeneration && format.info->colorEncoding == GL_SRGB)
if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
{
context->handleError(InvalidOperation()
<< "Mipmap generation of sRGB textures is not allowed.");
ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
return false;
}
......
......@@ -3138,6 +3138,85 @@ TEST_P(WebGLCompatibilityTest, DrawBuffers)
}
}
// Test that it's possible to generate mipmaps on unsized floating point textures once the
// extensions have been enabled
TEST_P(WebGLCompatibilityTest, GenerateMipmapUnsizedFloatingPointTexture)
{
if (extensionRequestable("GL_OES_texture_float"))
{
glRequestExtensionANGLE("GL_OES_texture_float");
}
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_OES_texture_float"));
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
constexpr GLColor32F data[4] = {
kFloatRed, kFloatRed, kFloatGreen, kFloatBlue,
};
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_FLOAT, data);
ASSERT_GL_NO_ERROR();
glGenerateMipmap(GL_TEXTURE_2D);
EXPECT_GL_NO_ERROR();
}
// Test that it's possible to generate mipmaps on unsized floating point textures once the
// extensions have been enabled
TEST_P(WebGLCompatibilityTest, GenerateMipmapSizedFloatingPointTexture)
{
if (extensionRequestable("GL_OES_texture_float"))
{
glRequestExtensionANGLE("GL_OES_texture_float");
}
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_OES_texture_float"));
if (extensionRequestable("GL_EXT_texture_storage"))
{
glRequestExtensionANGLE("GL_EXT_texture_storage");
}
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_EXT_texture_storage"));
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
constexpr GLColor32F data[4] = {
kFloatRed, kFloatRed, kFloatGreen, kFloatBlue,
};
glTexStorage2DEXT(GL_TEXTURE_2D, 2, GL_RGBA32F, 2, 2);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_FLOAT, data);
ASSERT_GL_NO_ERROR();
glGenerateMipmap(GL_TEXTURE_2D);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
if (extensionRequestable("GL_EXT_color_buffer_float"))
{
// Format is renderable but not filterable
glRequestExtensionANGLE("GL_EXT_color_buffer_float");
glGenerateMipmap(GL_TEXTURE_2D);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
if (extensionRequestable("GL_EXT_color_buffer_float_linear"))
{
// Format is renderable but not filterable
glRequestExtensionANGLE("GL_EXT_color_buffer_float_linear");
if (extensionEnabled("GL_EXT_color_buffer_float"))
{
// Format is filterable and renderable
glGenerateMipmap(GL_TEXTURE_2D);
EXPECT_GL_NO_ERROR();
}
else
{
// Format is filterable but not renderable
glGenerateMipmap(GL_TEXTURE_2D);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
}
}
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
// qualifiers.
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)
......
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