Commit f8fccb39 by Jamie Madill

Fix bugs in 2D Array Texture support.

This fixes assertion failures and other errors, reproducible by running the dEQP Texture Format tests. BUG=angle:813 Change-Id: I3b97f89323f9656b45f617211fb4579a24013951 Reviewed-on: https://chromium-review.googlesource.com/229351Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org>
parent e5685e08
...@@ -2362,7 +2362,7 @@ gl::Error TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset ...@@ -2362,7 +2362,7 @@ gl::Error TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset
const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL; const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
gl::Error error = TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, gl::Error error = TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type,
unpack, layerPixels, index); unpack, layerPixels, index);
if (error.isError()) if (error.isError())
{ {
...@@ -2513,7 +2513,7 @@ void TextureD3D_2DArray::initMipmapsImages() ...@@ -2513,7 +2513,7 @@ void TextureD3D_2DArray::initMipmapsImages()
{ {
int baseWidth = getBaseLevelWidth(); int baseWidth = getBaseLevelWidth();
int baseHeight = getBaseLevelHeight(); int baseHeight = getBaseLevelHeight();
int baseDepth = getBaseLevelDepth(); int baseDepth = getLayerCount(0);
GLenum baseFormat = getBaseLevelInternalFormat(); GLenum baseFormat = getBaseLevelInternalFormat();
// Purge array levels 1 through q and reset them to represent the generated mipmap levels. // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
......
...@@ -1790,13 +1790,16 @@ TextureStorage11_2DArray::~TextureStorage11_2DArray() ...@@ -1790,13 +1790,16 @@ TextureStorage11_2DArray::~TextureStorage11_2DArray()
{ {
for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++) for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++)
{ {
bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this); if (i->second)
ASSERT(imageAssociationCorrect);
if (imageAssociationCorrect)
{ {
// We must let the Images recover their data before we delete it from the TextureStorage. bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this);
i->second->recoverFromAssociatedStorage(); ASSERT(imageAssociationCorrect);
if (imageAssociationCorrect)
{
// We must let the Images recover their data before we delete it from the TextureStorage.
i->second->recoverFromAssociatedStorage();
}
} }
} }
mAssociatedImages.clear(); mAssociatedImages.clear();
...@@ -1874,8 +1877,6 @@ gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex ...@@ -1874,8 +1877,6 @@ gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex
LevelLayerKey key(level, layerTarget); LevelLayerKey key(level, layerTarget);
ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
if (mAssociatedImages.find(key) != mAssociatedImages.end()) if (mAssociatedImages.find(key) != mAssociatedImages.end())
{ {
if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage) if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage)
......
...@@ -112,6 +112,89 @@ protected: ...@@ -112,6 +112,89 @@ protected:
GLint mTextureScaleUniformLocation; GLint mTextureScaleUniformLocation;
}; };
ANGLE_TYPED_TEST_CASE(TextureTestES3, ES3_D3D11);
template<typename T>
class TextureTestES3 : public TextureTest<T>
{
protected:
virtual void SetUp()
{
TextureTest::SetUp();
glGenTextures(1, &mTextureArray);
EXPECT_GL_NO_ERROR();
ASSERT_GL_NO_ERROR();
const std::string vertexShaderSource = SHADER_SOURCE
(
#version 300 es\n
precision highp float;
in vec4 position;
out vec2 texcoord;
uniform vec2 textureScale;
void main()
{
gl_Position = vec4(position.xy * textureScale, 0.0, 1.0);
texcoord = (position.xy * 0.5) + 0.5;
}
);
const std::string fragmentShaderSourceArray = SHADER_SOURCE
(
#version 300 es\n
precision highp float;
uniform sampler2DArray tex;
uniform int slice;
in vec2 texcoord;
out vec4 out_FragColor;
void main()
{
out_FragColor = texture(tex, vec3(texcoord, float(slice)));
}
);
mArrayProgram = CompileProgram(vertexShaderSource, fragmentShaderSourceArray);
if (mArrayProgram == 0)
{
FAIL() << "shader compilation failed.";
}
mTextureArrayUniformLocation = glGetUniformLocation(mArrayProgram, "tex");
ASSERT_NE(-1, mTextureArrayUniformLocation);
mTextureArrayScaleUniformLocation = glGetUniformLocation(mArrayProgram, "textureScale");
ASSERT_NE(-1, mTextureArrayScaleUniformLocation);
mTextureArraySliceUniformLocation = glGetUniformLocation(mArrayProgram, "slice");
ASSERT_NE(-1, mTextureArraySliceUniformLocation);
glUseProgram(mArrayProgram);
glUniform2f(mTextureArrayScaleUniformLocation, 1.0f, 1.0f);
glUseProgram(0);
ASSERT_GL_NO_ERROR();
}
virtual void TearDown()
{
glDeleteTextures(1, &mTextureArray);
glDeleteProgram(mArrayProgram);
TextureTest::TearDown();
}
GLuint mTextureArray;
GLuint mArrayProgram;
GLint mTextureArrayUniformLocation;
GLint mTextureArrayScaleUniformLocation;
GLint mTextureArraySliceUniformLocation;
};
TYPED_TEST(TextureTest, NegativeAPISubImage) TYPED_TEST(TextureTest, NegativeAPISubImage)
{ {
glBindTexture(GL_TEXTURE_2D, mTexture2D); glBindTexture(GL_TEXTURE_2D, mTexture2D);
...@@ -224,3 +307,86 @@ TYPED_TEST(TextureTest, MipmapsTwice) ...@@ -224,3 +307,86 @@ TYPED_TEST(TextureTest, MipmapsTwice)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255); EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
} }
// Creates a mipmapped 2D array texture with three layers, and calls ANGLE's GenerateMipmap.
// Then tests if the mipmaps are rendered correctly for all three layers.
TYPED_TEST(TextureTestES3, MipmapsForTextureArray)
{
int px = getWindowWidth() / 2;
int py = getWindowHeight() / 2;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 5, GL_RGBA8, 16, 16, 3);
// Fill the first layer with red
std::vector<GLubyte> pixels(4 * 16 * 16);
for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
{
pixels[pixelId * 4 + 0] = 255;
pixels[pixelId * 4 + 1] = 0;
pixels[pixelId * 4 + 2] = 0;
pixels[pixelId * 4 + 3] = 255;
}
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
// Fill the second layer with green
for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
{
pixels[pixelId * 4 + 0] = 0;
pixels[pixelId * 4 + 1] = 255;
pixels[pixelId * 4 + 2] = 0;
pixels[pixelId * 4 + 3] = 255;
}
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
// Fill the third layer with blue
for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId)
{
pixels[pixelId * 4 + 0] = 0;
pixels[pixelId * 4 + 1] = 0;
pixels[pixelId * 4 + 2] = 255;
pixels[pixelId * 4 + 3] = 255;
}
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
EXPECT_GL_NO_ERROR();
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
EXPECT_GL_NO_ERROR();
glUseProgram(mArrayProgram);
glUniform1i(mTextureArrayUniformLocation, 0);
glUniform2f(mTextureScaleUniformLocation, 0.0625f, 0.0625f);
EXPECT_GL_NO_ERROR();
// Draw the first slice
glUseProgram(mArrayProgram);
glUniform1i(mTextureArraySliceUniformLocation, 0);
drawQuad(mArrayProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(px, py, 255, 0, 0, 255);
// Draw the second slice
glUseProgram(mArrayProgram);
glUniform1i(mTextureArraySliceUniformLocation, 1);
drawQuad(mArrayProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(px, py, 0, 255, 0, 255);
// Draw the third slice
glUseProgram(mArrayProgram);
glUniform1i(mTextureArraySliceUniformLocation, 2);
drawQuad(mArrayProgram, "position", 0.5f);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_EQ(px, py, 0, 0, 255, 255);
}
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