зеркало из https://github.com/AvaloniaUI/angle.git
D3D: Reallocate storage when texture format changes with base level
Different levels of the same texture may have different formats, so changing the base level may affect the format that should be used for the storage. Take this into account in the D3D backend. The added test fails on some GL drivers. TEST=angle_end2end_tests BUG=angleproject:596 Change-Id: I5380e942694a75685ebb510edb01c0489e0d5179 Reviewed-on: https://chromium-review.googlesource.com/344230 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
This commit is contained in:
Родитель
77ae8d578b
Коммит
87fc71c456
|
@ -649,6 +649,7 @@ void TextureD3D::setBaseLevel(GLuint baseLevel)
|
|||
const int oldStorageWidth = std::max(1, getLevelZeroWidth());
|
||||
const int oldStorageHeight = std::max(1, getLevelZeroHeight());
|
||||
const int oldStorageDepth = std::max(1, getLevelZeroDepth());
|
||||
const int oldStorageFormat = getBaseLevelInternalFormat();
|
||||
mBaseLevel = baseLevel;
|
||||
|
||||
// When the base level changes, the texture storage might not be valid anymore, since it could
|
||||
|
@ -656,8 +657,10 @@ void TextureD3D::setBaseLevel(GLuint baseLevel)
|
|||
const int newStorageWidth = std::max(1, getLevelZeroWidth());
|
||||
const int newStorageHeight = std::max(1, getLevelZeroHeight());
|
||||
const int newStorageDepth = std::max(1, getLevelZeroDepth());
|
||||
if (mTexStorage && (newStorageWidth != oldStorageWidth ||
|
||||
newStorageHeight != oldStorageHeight || newStorageDepth != oldStorageDepth))
|
||||
const int newStorageFormat = getBaseLevelInternalFormat();
|
||||
if (mTexStorage &&
|
||||
(newStorageWidth != oldStorageWidth || newStorageHeight != oldStorageHeight ||
|
||||
newStorageDepth != oldStorageDepth || newStorageFormat != oldStorageFormat))
|
||||
{
|
||||
markAllImagesDirty();
|
||||
SafeDelete(mTexStorage);
|
||||
|
|
|
@ -2171,6 +2171,65 @@ TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange)
|
|||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
|
||||
// Test that changing base level works when it affects the format of the texture.
|
||||
TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel)
|
||||
{
|
||||
if (IsNVIDIA() && (isOpenGL() || isGLES()))
|
||||
{
|
||||
// Observed rendering corruption on NVIDIA OpenGL.
|
||||
std::cout << "Test skipped on NVIDIA OpenGL." << std::endl;
|
||||
return;
|
||||
}
|
||||
if (IsIntel() && isOpenGL())
|
||||
{
|
||||
// Observed incorrect rendering on Intel OpenGL.
|
||||
std::cout << "Test skipped on Intel OpenGL." << std::endl;
|
||||
return;
|
||||
}
|
||||
if (IsAMD() && isOpenGL())
|
||||
{
|
||||
// Observed incorrect rendering on AMD OpenGL.
|
||||
std::cout << "Test skipped on AMD OpenGL." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mTexture2D);
|
||||
std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan);
|
||||
std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
|
||||
// RGBA8 level that's initially unused.
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
texDataCyan.data());
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
|
||||
// RG8 level that's initially used, with consistent dimensions with level 0 but a different
|
||||
// format. It reads green channel data from the green and alpha channels of texDataGreen
|
||||
// (this is a bit hacky but works).
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data());
|
||||
|
||||
EXPECT_GL_NO_ERROR();
|
||||
|
||||
drawQuad(mProgram, "position", 0.5f);
|
||||
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
|
||||
// Switch the texture to use the cyan level 0 with the RGBA format.
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
||||
EXPECT_GL_NO_ERROR();
|
||||
|
||||
drawQuad(mProgram, "position", 0.5f);
|
||||
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
|
||||
}
|
||||
|
||||
// Test that setting a texture image works when base level is out of range.
|
||||
TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange)
|
||||
{
|
||||
|
|
|
@ -615,6 +615,11 @@ bool ANGLETest::isOpenGL() const
|
|||
return getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
|
||||
}
|
||||
|
||||
bool ANGLETest::isGLES() const
|
||||
{
|
||||
return getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
|
||||
}
|
||||
|
||||
EGLint ANGLETest::getPlatformRenderer() const
|
||||
{
|
||||
assert(mEGLWindow);
|
||||
|
|
|
@ -171,6 +171,7 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
|
|||
bool isMultisampleEnabled() const;
|
||||
|
||||
bool isOpenGL() const;
|
||||
bool isGLES() const;
|
||||
EGLint getPlatformRenderer() const;
|
||||
|
||||
void ignoreD3D11SDKLayersWarnings();
|
||||
|
|
Загрузка…
Ссылка в новой задаче