blob: 852dcf82014e8be4430787944d88c32496c1714a [file] [log] [blame]
//
// Copyright 2015 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.
//
#include "test_utils/ANGLETest.h"
using namespace angle;
class FramebufferRenderMipmapTest : public ANGLETest
{
protected:
FramebufferRenderMipmapTest()
{
setWindowWidth(256);
setWindowHeight(256);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
virtual void SetUp()
{
ANGLETest::SetUp();
const std::string vsSource =
R"(attribute highp vec4 position;
void main(void)
{
gl_Position = position;
})";
const std::string fsSource =
R"(uniform highp vec4 color;
void main(void)
{
gl_FragColor = color;
})";
mProgram = CompileProgram(vsSource, fsSource);
if (mProgram == 0)
{
FAIL() << "shader compilation failed.";
}
mColorLocation = glGetUniformLocation(mProgram, "color");
glUseProgram(mProgram);
glClearColor(0, 0, 0, 0);
glClearDepthf(0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
ASSERT_GL_NO_ERROR();
}
virtual void TearDown()
{
glDeleteProgram(mProgram);
ANGLETest::TearDown();
}
GLuint mProgram;
GLint mColorLocation;
};
// Validate that if we are in ES3 or GL_OES_fbo_render_mipmap exists, there are no validation errors
// when using a non-zero level in glFramebufferTexture2D.
TEST_P(FramebufferRenderMipmapTest, Validation)
{
bool renderToMipmapSupported =
extensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
GLuint tex = 0;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
const GLint levels = 5;
for (GLint i = 0; i < levels; i++)
{
GLsizei size = 1 << ((levels - 1) - i);
glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
EXPECT_GL_NO_ERROR();
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
EXPECT_GL_NO_ERROR();
for (GLint i = 0; i < levels; i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
if (i > 0 && !renderToMipmapSupported)
{
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
else
{
EXPECT_GL_NO_ERROR();
EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GLenum(GL_FRAMEBUFFER_COMPLETE));
}
}
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &tex);
}
// Render to various levels of a texture and check that they have the correct color data via ReadPixels
TEST_P(FramebufferRenderMipmapTest, RenderToMipmap)
{
bool renderToMipmapSupported =
extensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
if (!renderToMipmapSupported)
{
std::cout << "Test skipped because GL_OES_fbo_render_mipmap or ES3 is not available." << std::endl;
return;
}
const GLfloat levelColors[] =
{
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
};
const GLint testLevels = static_cast<GLint>(ArraySize(levelColors) / 4);
GLuint tex = 0;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
for (GLint i = 0; i < testLevels; i++)
{
GLsizei size = 1 << ((testLevels - 1) - i);
glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
EXPECT_GL_NO_ERROR();
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
EXPECT_GL_NO_ERROR();
// Render to the levels of the texture with different colors
for (GLint i = 0; i < testLevels; i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
EXPECT_GL_NO_ERROR();
glUseProgram(mProgram);
glUniform4fv(mColorLocation, 1, levelColors + (i * 4));
drawQuad(mProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
}
// Test that the levels of the texture are correct
for (GLint i = 0; i < testLevels; i++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
EXPECT_GL_NO_ERROR();
const GLfloat *color = levelColors + (i * 4);
EXPECT_PIXEL_EQ(0, 0, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255);
}
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &tex);
EXPECT_GL_NO_ERROR();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(FramebufferRenderMipmapTest,
ES2_D3D9(),
ES2_D3D11(),
ES3_D3D11(),
ES2_OPENGL(),
ES3_OPENGL(),
ES2_OPENGLES(),
ES3_OPENGLES());