[Impeller] dont generate final 1x1 mip level to work around Adreno GPU bug (#161192)
Generating the final 1x1 mip level of a texture causes the entire texture to become corrupted on some Adreno GPUs. https://github.com/flutter/flutter/issues/160441 https://github.com/flutter/flutter/issues/159876 https://github.com/flutter/flutter/issues/160587
This commit is contained in:
parent
16b9fe049d
commit
434ca754e3
@ -578,11 +578,11 @@ TEST(GeometryTest, QuaternionVectorMultiply) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(GeometryTest, CanGenerateMipCounts) {
|
TEST(GeometryTest, CanGenerateMipCounts) {
|
||||||
ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
|
ASSERT_EQ((Size{128, 128}.MipCount()), 6u);
|
||||||
ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
|
ASSERT_EQ((Size{128, 256}.MipCount()), 7u);
|
||||||
ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
|
ASSERT_EQ((Size{128, 130}.MipCount()), 7u);
|
||||||
ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
|
ASSERT_EQ((Size{128, 257}.MipCount()), 8u);
|
||||||
ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
|
ASSERT_EQ((Size{257, 128}.MipCount()), 8u);
|
||||||
ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
|
ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
|
||||||
ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
|
ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
|
||||||
ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
|
ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
|
||||||
|
@ -131,12 +131,25 @@ struct TSize {
|
|||||||
static_cast<Type>(std::ceil(other.height))};
|
static_cast<Type>(std::ceil(other.height))};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the mip count of the texture.
|
||||||
|
///
|
||||||
|
/// Note: does not count the final 1x1 mip level, both for practical reasons
|
||||||
|
/// and to workaround driver bugs.
|
||||||
constexpr size_t MipCount() const {
|
constexpr size_t MipCount() const {
|
||||||
constexpr size_t minimum_mip = 1u;
|
constexpr size_t minimum_mip = 1u;
|
||||||
if (IsEmpty()) {
|
if (IsEmpty()) {
|
||||||
return minimum_mip;
|
return minimum_mip;
|
||||||
}
|
}
|
||||||
size_t result = std::max(ceil(log2(width)), ceil(log2(height)));
|
size_t result = std::max(ceil(log2(width)), ceil(log2(height)));
|
||||||
|
// This check avoids creating 1x1 mip levels, which are both pointless
|
||||||
|
// and cause rendering problems on some Adreno GPUs.
|
||||||
|
// See:
|
||||||
|
// * https://github.com/flutter/flutter/issues/160441
|
||||||
|
// * https://github.com/flutter/flutter/issues/159876
|
||||||
|
// * https://github.com/flutter/flutter/issues/160587
|
||||||
|
if (result > 1) {
|
||||||
|
result -= 1;
|
||||||
|
}
|
||||||
return std::max(result, minimum_mip);
|
return std::max(result, minimum_mip);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user