зеркало из https://github.com/AvaloniaUI/angle.git
Fix Texture2DTest.TextureSize.
This CL fixes a number of issues: fixes the calls to texture size query, fixes an uninitialized memory read, fixes some incomplete texture cases, and fixes an out-of-bounds with the color array. It also cleans up the test logic, and splits the test into four sub-tests so it runs more smoothly in CI. Noticed while working on the capture/replay harness with ASAN. Bug: angleproject:5982 Change-Id: I15459381b92332db5adad2bd91c0b9eb0f8b5961 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3104005 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Yuly Novikov <ynovikov@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
b2238a3c14
Коммит
02005fdc89
|
@ -373,6 +373,8 @@ void main()
|
|||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
void testTextureSize(int testCaseIndex);
|
||||
|
||||
GLuint mTexture2D;
|
||||
GLint mTexture2DUniformLocation;
|
||||
};
|
||||
|
@ -3239,81 +3241,45 @@ void FillLevel(GLint level,
|
|||
GLuint width,
|
||||
GLuint height,
|
||||
const GLColor &color,
|
||||
bool opt_cubemap,
|
||||
bool opt_subTex)
|
||||
bool cubemap,
|
||||
bool subTex)
|
||||
{
|
||||
GLsizei numPixels = width * height;
|
||||
std::unique_ptr<uint8_t[]> pixels;
|
||||
GLsizei largeDim = std::max(width, height);
|
||||
GLsizei smallDim = std::min(width, height);
|
||||
|
||||
std::unique_ptr<uint8_t[]> pixelRow = std::make_unique<uint8_t[]>(largeDim * 4);
|
||||
for (GLint jj = 0; jj < largeDim; ++jj)
|
||||
std::vector<GLColor> pixels(width * height, color);
|
||||
std::vector<GLenum> targets;
|
||||
if (cubemap)
|
||||
{
|
||||
GLsizei off = jj * 4;
|
||||
pixelRow[off + 0] = color[0];
|
||||
pixelRow[off + 1] = color[1];
|
||||
pixelRow[off + 2] = color[2];
|
||||
pixelRow[off + 3] = color[3];
|
||||
}
|
||||
|
||||
if (largeDim == numPixels)
|
||||
{
|
||||
pixels = std::move(pixelRow);
|
||||
targets = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
|
||||
}
|
||||
else
|
||||
{
|
||||
pixels = std::make_unique<uint8_t[]>(numPixels * 4);
|
||||
for (GLint jj = 0; jj < smallDim; ++jj)
|
||||
{
|
||||
GLsizei off = jj * largeDim * 4;
|
||||
memcpy(pixels.get() + off, pixelRow.get(), largeDim * 4);
|
||||
}
|
||||
targets = {GL_TEXTURE_2D};
|
||||
}
|
||||
|
||||
if (opt_cubemap)
|
||||
for (GLenum target : targets)
|
||||
{
|
||||
std::array<GLenum, 6> targets = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
|
||||
for (GLenum target : targets)
|
||||
if (subTex)
|
||||
{
|
||||
if (opt_subTex)
|
||||
{
|
||||
glTexSubImage2D(target, level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
pixels.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
pixels.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opt_subTex)
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
pixels.get());
|
||||
glTexSubImage2D(target, level, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
pixels.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
pixels.get());
|
||||
glTexImage2D(target, level, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
pixels.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is part of tests that webgl_conformance_vulkan_passthrough_tests
|
||||
// conformance/textures/misc/texture-size.html does
|
||||
TEST_P(Texture2DTest, TextureSize)
|
||||
void Texture2DTest::testTextureSize(int testCaseIndex)
|
||||
{
|
||||
// http://anglebug.com/5982
|
||||
ANGLE_SKIP_TEST_IF(IsLinux() && IsTSan() && (IsOpenGL() || IsVulkan()));
|
||||
// http://anglebug.com/6296
|
||||
ANGLE_SKIP_TEST_IF(IsMetal());
|
||||
|
||||
const GLColor kNewMipColors[] = {
|
||||
std::array<GLColor, 6> kNewMipColors = {
|
||||
GLColor::green, GLColor::red, GLColor::blue,
|
||||
GLColor::yellow, GLColor::magenta, GLColor::cyan,
|
||||
};
|
||||
|
@ -3339,108 +3305,129 @@ void main()
|
|||
{
|
||||
gl_FragColor = textureCube(tex, texcoord);
|
||||
})";
|
||||
GLuint programCubeMap = CompileProgram(kVS, kFS);
|
||||
ASSERT_NE(0u, programCubeMap);
|
||||
ANGLE_GL_PROGRAM(programCubeMap, kVS, kFS);
|
||||
GLint textureCubeUniformLocation = glGetUniformLocation(programCubeMap, "tex");
|
||||
ASSERT_NE(-1, textureCubeUniformLocation);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLint max2DSize, maxCubeMapSize;
|
||||
glGetTexParameteriv(GL_TEXTURE_2D, GL_MAX_TEXTURE_SIZE, &max2DSize);
|
||||
glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapSize);
|
||||
// Assuming 2048x2048xRGBA (22meg with mips) will run on all WebGL platforms
|
||||
GLint max2DSize = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
|
||||
GLint maxCubeMapSize = 0;
|
||||
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapSize);
|
||||
// Assuming 2048x2048xRGBA (22 mb with mips) will run on all WebGL platforms
|
||||
GLint max2DSquareSize = std::min(max2DSize, 2048);
|
||||
// I'd prefer this to be 2048 but that's 16meg x 6 faces or 128meg (with mips)
|
||||
// 1024 is 33.5 meg (with mips)
|
||||
// I'd prefer this to be 2048 but that's 16 mb x 6 faces or 128 mb (with mips)
|
||||
// 1024 is 33.5 mb (with mips)
|
||||
maxCubeMapSize = std::min(maxCubeMapSize, 1024);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
GLint power = 0;
|
||||
GLint size = std::pow(2, power);
|
||||
GLint texWidth, texHeight;
|
||||
|
||||
while (size <= max2DSize)
|
||||
for (GLint size = 1; size <= max2DSize; size *= 2)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
bool cubeMap = testCaseIndex == 3;
|
||||
GLenum texTarget = cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||
GLuint program = cubeMap ? programCubeMap : mProgram;
|
||||
GLint texWidth = 0, texHeight = 0;
|
||||
|
||||
switch (testCaseIndex)
|
||||
{
|
||||
bool cubeMap = i == 3 ? true : false;
|
||||
GLenum texTarget = cubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
texWidth = size;
|
||||
texHeight = 1;
|
||||
break;
|
||||
case 1:
|
||||
texWidth = 1;
|
||||
texHeight = size;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
texWidth = size;
|
||||
texHeight = size;
|
||||
break;
|
||||
}
|
||||
|
||||
if (texWidth == texHeight && size > max2DSquareSize)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cubeMap && size > maxCubeMapSize)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GLuint texture;
|
||||
glGenTextures(1, &texture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(texTarget, texture);
|
||||
glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
|
||||
|
||||
if (cubeMap)
|
||||
{
|
||||
glUseProgram(programCubeMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
glUseProgram(mProgram);
|
||||
}
|
||||
glUniform1i(mTexture2DUniformLocation, 0);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
drawQuad(mProgram, "position", 1.0f);
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
|
||||
|
||||
colorCount = (colorCount + 1) % sizeof(kNewMipColors);
|
||||
FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
|
||||
glGenerateMipmap(texTarget);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
|
||||
glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
drawQuad(mProgram, "position", 1.0f);
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
|
||||
|
||||
colorCount = (colorCount + 1) % sizeof(kNewMipColors);
|
||||
FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, true);
|
||||
glGenerateMipmap(texTarget);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
drawQuad(mProgram, "position", 1.0f);
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
|
||||
glDeleteTextures(1, &texture);
|
||||
case 0:
|
||||
texWidth = size;
|
||||
texHeight = 1;
|
||||
break;
|
||||
case 1:
|
||||
texWidth = 1;
|
||||
texHeight = size;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
texWidth = size;
|
||||
texHeight = size;
|
||||
break;
|
||||
}
|
||||
|
||||
++power;
|
||||
size = std::pow(2, power);
|
||||
if (texWidth == texHeight && size > max2DSquareSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cubeMap && size > maxCubeMapSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GLTexture texture;
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(texTarget, texture);
|
||||
FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
|
||||
glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glUseProgram(program);
|
||||
if (cubeMap)
|
||||
{
|
||||
glUniform1i(textureCubeUniformLocation, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glUniform1i(mTexture2DUniformLocation, 0);
|
||||
}
|
||||
|
||||
drawQuad(program, "position", 1.0f);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
|
||||
|
||||
colorCount = (colorCount + 1) % kNewMipColors.size();
|
||||
FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, false);
|
||||
glGenerateMipmap(texTarget);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
drawQuad(program, "position", 1.0f);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
|
||||
|
||||
colorCount = (colorCount + 1) % kNewMipColors.size();
|
||||
FillLevel(0, texWidth, texHeight, kNewMipColors[colorCount], cubeMap, true);
|
||||
glGenerateMipmap(texTarget);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
drawQuad(program, "position", 1.0f);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, kNewMipColors[colorCount]);
|
||||
}
|
||||
}
|
||||
|
||||
// Permutation 0 of testTextureSize.
|
||||
TEST_P(Texture2DTest, TextureSizeCase0)
|
||||
{
|
||||
testTextureSize(0);
|
||||
}
|
||||
|
||||
// Permutation 1 of testTextureSize.
|
||||
TEST_P(Texture2DTest, TextureSizeCase1)
|
||||
{
|
||||
testTextureSize(1);
|
||||
}
|
||||
|
||||
// Permutation 2 of testTextureSize.
|
||||
TEST_P(Texture2DTest, TextureSizeCase2)
|
||||
{
|
||||
testTextureSize(2);
|
||||
}
|
||||
|
||||
// Permutation 3 of testTextureSize.
|
||||
TEST_P(Texture2DTest, TextureSizeCase3)
|
||||
{
|
||||
testTextureSize(3);
|
||||
}
|
||||
|
||||
// Test that drawing works correctly RGBA 3D texture
|
||||
TEST_P(Texture3DTestES2, RGBA)
|
||||
{
|
||||
|
@ -8184,7 +8171,7 @@ class Texture2DDepthTest : public Texture2DTest
|
|||
}
|
||||
};
|
||||
|
||||
// Test depth texture compatibility with OES_depth_texture. Uses unsized internformat.
|
||||
// Test depth texture compatibility with OES_depth_texture. Uses unsized internal format.
|
||||
TEST_P(Texture2DDepthTest, DepthTextureES2Compatibility)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(IsD3D11());
|
||||
|
|
Загрузка…
Ссылка в новой задаче