Commit 5ff8cae9 by Geoff Lang Committed by Commit Bot

GL/D3D: Use texture uploads instead of clearing for robust init.

Chrome uses regular texture uploads on all platforms except OpenGL on Mac to do robust resource init for textures because multiple bugs have been observed with texture corruption. BUG=883276 BUG=882580 BUG=941620 Change-Id: I5fcd6862147822a08c7533e6a6a9277223034ebd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1669104Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 4c0a2361
......@@ -204,6 +204,14 @@ struct FeaturesD3D : FeatureSetBase
"On an NVIDIA D3D driver, the return value from RWByteAddressBuffer.InterlockedAdd does "
"not resolve when used in the .yzw components of a RWByteAddressBuffer.Store operation",
&members, "http://anglebug.com/3246"};
// Match chromium's robust resource init behaviour by always prefering to upload texture data
// instead of clearing. Clear calls have been observed to cause texture corruption for some
// formats.
Feature allowClearForRobustResourceInit = {
"allow_clear_for_robust_resource_init", FeatureCategory::D3DWorkarounds,
"Some drivers corrupt texture data when clearing for robust resource initialization.",
&members, "http://crbug.com/941620"};
};
inline FeaturesD3D::FeaturesD3D() = default;
......
......@@ -281,6 +281,17 @@ struct FeaturesGL : FeatureSetBase
"max_msaa_sample_count_4", FeatureCategory::OpenGLWorkarounds,
"Various rendering bugs have been observed when using higher MSAA counts on Android",
&members, "http://crbug.com/797243"};
// Prefer to do the robust resource init clear using a glClear. Calls to TexSubImage2D on large
// textures can take hundreds of milliseconds because of slow uploads on macOS. Do this only on
// macOS because clears are buggy on other drivers.
// https://crbug.com/848952 (slow uploads on macOS)
// https://crbug.com/883276 (buggy clears on Android)
Feature allowClearForRobustResourceInit = {
"allow_clear_for_robust_resource_init", FeatureCategory::OpenGLWorkarounds,
"Using glClear for robust resource initialization is buggy on some drivers and leads to "
"texture corruption. Default to data uploads except on MacOS where it is very slow.",
&members, "http://crbug.com/883276"};
};
inline FeaturesGL::FeaturesGL() = default;
......
......@@ -732,8 +732,10 @@ angle::Result TextureD3D::initializeContents(const gl::Context *context,
// Fast path: can use a render target clear.
// We don't use the fast path with the zero max lod workaround because it would introduce a race
// between the rendertarget and the staging images.
if (canCreateRenderTargetForImage(index) &&
!mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
const angle::FeaturesD3D &features = mRenderer->getFeatures();
bool shouldUseClear = (image == nullptr);
if (canCreateRenderTargetForImage(index) && !features.zeroMaxLodWorkaround.enabled &&
(shouldUseClear || features.allowClearForRobustResourceInit.enabled))
{
ANGLE_TRY(ensureRenderTarget(context));
ASSERT(mTexStorage);
......@@ -743,6 +745,8 @@ angle::Result TextureD3D::initializeContents(const gl::Context *context,
return angle::Result::Continue;
}
ASSERT(image != nullptr);
// Slow path: non-renderable texture or the texture levels aren't set up.
const auto &formatInfo = gl::GetSizedInternalFormatInfo(image->getInternalFormat());
......
......@@ -2448,6 +2448,9 @@ void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps,
features->selectViewInGeometryShader.enabled =
(deviceCaps.supportsVpRtIndexWriteFromVertexShader == false);
// Never clear for robust resource init. This matches Chrome's texture clearning behaviour.
features->allowClearForRobustResourceInit.enabled = false;
// Call platform hooks for testing overrides.
auto *platform = ANGLEPlatformCurrent();
platform->overrideWorkaroundsD3D(platform, features);
......
......@@ -812,6 +812,9 @@ void InitializeFeatures(angle::FeaturesD3D *features)
// TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
features->expandIntegerPowExpressions.enabled = true;
// Never clear for robust resource init. This matches Chrome's texture clearning behaviour.
features->allowClearForRobustResourceInit.enabled = false;
// Call platform hooks for testing overrides.
auto *platform = ANGLEPlatformCurrent();
platform->overrideWorkaroundsD3D(platform, features);
......
......@@ -1595,9 +1595,11 @@ angle::Result TextureGL::initializeContents(const gl::Context *context,
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
bool shouldUseClear = !nativegl::SupportsTexImage(getType());
GLenum nativeInternalFormat =
getLevelInfo(imageIndex.getTarget(), imageIndex.getLevelIndex()).nativeInternalFormat;
if (nativegl::SupportsNativeRendering(functions, mState.getType(), nativeInternalFormat))
if ((features.allowClearForRobustResourceInit.enabled || shouldUseClear) &&
nativegl::SupportsNativeRendering(functions, mState.getType(), nativeInternalFormat))
{
BlitGL *blitter = GetBlitGL(context);
......@@ -1614,6 +1616,7 @@ angle::Result TextureGL::initializeContents(const gl::Context *context,
// Either the texture is not renderable or was incomplete when clearing, fall back to a data
// upload
ASSERT(nativegl::SupportsTexImage(getType()));
const gl::ImageDesc &desc = mState.getImageDesc(imageIndex);
const gl::InternalFormat &internalFormatInfo = *desc.format.info;
......@@ -1621,6 +1624,7 @@ angle::Result TextureGL::initializeContents(const gl::Context *context,
unpackState.alignment = 1;
stateManager->setPixelUnpackState(unpackState);
stateManager->bindTexture(getType(), mTextureID);
if (internalFormatInfo.compressed)
{
nativegl::CompressedTexSubImageFormat nativeSubImageFormat =
......
......@@ -1505,6 +1505,8 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
features->limitMaxTextureSizeTo4096.enabled = IsAndroid();
features->limitMaxMSAASamplesTo4.enabled = IsAndroid();
features->allowClearForRobustResourceInit.enabled = IsApple();
}
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
......@@ -1562,6 +1564,20 @@ bool SupportsNativeRendering(const FunctionsGL *functions,
}
}
bool SupportsTexImage(gl::TextureType type)
{
switch (type)
{
// Multi-sample texture types only support TexStorage data upload
case gl::TextureType::_2DMultisample:
case gl::TextureType::_2DMultisampleArray:
return false;
default:
return true;
}
}
bool UseTexImage2D(gl::TextureType textureType)
{
return textureType == gl::TextureType::_2D || textureType == gl::TextureType::CubeMap ||
......
......@@ -77,6 +77,7 @@ bool SupportsOcclusionQueries(const FunctionsGL *functions);
bool SupportsNativeRendering(const FunctionsGL *functions,
gl::TextureType type,
GLenum internalFormat);
bool SupportsTexImage(gl::TextureType type);
bool UseTexImage2D(gl::TextureType textureType);
bool UseTexImage3D(gl::TextureType textureType);
GLenum GetTextureBindingQuery(gl::TextureType textureType);
......
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