From 47cdac4b96daf88ca0e2aac1cc5476efc42db36c Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 5 Dec 2019 13:02:14 -0500 Subject: [PATCH] Restrict the slow texture upload workaround to 128bit formats. (#21) The workaround is slow for having a CPU-visible mirror of the texture, but that mirror is not properly recycled with regards to GPU usage, thus causing a CPU stall on update. Original reports were related to WebRender vertex texture updates that are RGBA32F and RGBA32U formats. Limiting the workaround to these formats would allow the affected platforms to upload regular texture data faster without stalls. Co-authored-by: Erich Gubler --- .../platform/autogen/FeaturesD3D_autogen.h | 6 ++++++ include/platform/d3d_features.json | 7 +++++++ src/libANGLE/renderer/d3d/TextureD3D.cpp | 21 +++++++++++++++++-- src/libANGLE/renderer/d3d/TextureD3D.h | 1 + .../renderer/d3d/d3d11/renderer11_utils.cpp | 6 ++++-- .../renderer/d3d/d3d9/renderer9_utils.cpp | 1 + util/autogen/angle_features_autogen.cpp | 1 + util/autogen/angle_features_autogen.h | 1 + 8 files changed, 40 insertions(+), 4 deletions(-) diff --git a/include/platform/autogen/FeaturesD3D_autogen.h b/include/platform/autogen/FeaturesD3D_autogen.h index c690b444ed..6c29dc7f81 100644 --- a/include/platform/autogen/FeaturesD3D_autogen.h +++ b/include/platform/autogen/FeaturesD3D_autogen.h @@ -38,6 +38,12 @@ struct FeaturesD3D : FeatureSetBase &members, }; + FeatureInfo setDataFasterThanImageUploadOn128bitFormats = { + "setDataFasterThanImageUploadOn128bitFormats", + FeatureCategory::D3DWorkarounds, + &members, + }; + FeatureInfo zeroMaxLodWorkaround = { "zeroMaxLodWorkaround", FeatureCategory::D3DWorkarounds, diff --git a/include/platform/d3d_features.json b/include/platform/d3d_features.json index 14746940e6..175ed88d90 100644 --- a/include/platform/d3d_features.json +++ b/include/platform/d3d_features.json @@ -28,6 +28,13 @@ "Set data faster than image upload" ] }, + { + "name": "set_data_faster_than_image_upload_on_128bit_formats", + "category": "Workarounds", + "description": [ + "Set data faster than image upload on 128bit formats" + ] + }, { "name": "zero_max_lod_workaround", "category": "Workarounds", diff --git a/src/libANGLE/renderer/d3d/TextureD3D.cpp b/src/libANGLE/renderer/d3d/TextureD3D.cpp index 4c32ef8444..bbfc65f85c 100644 --- a/src/libANGLE/renderer/d3d/TextureD3D.cpp +++ b/src/libANGLE/renderer/d3d/TextureD3D.cpp @@ -284,13 +284,30 @@ angle::Result TextureD3D::setStorageExternalMemory(const gl::Context *context, return angle::Result::Continue; } -bool TextureD3D::shouldUseSetData(const ImageD3D *image) const +bool TextureD3D::couldUseSetData() const { if (!mRenderer->getFeatures().setDataFasterThanImageUpload.enabled) { return false; } + if (!mRenderer->getFeatures().setDataFasterThanImageUploadOn128bitFormats.enabled) + { + gl::InternalFormat internalFormat = + gl::GetSizedInternalFormatInfo(getBaseLevelInternalFormat()); + return internalFormat.pixelBytes < 16; + } + + return true; +} + +bool TextureD3D::shouldUseSetData(const ImageD3D *image) const +{ + if (!couldUseSetData()) + { + return false; + } + if (image->isDirty()) { return false; @@ -573,7 +590,7 @@ angle::Result TextureD3D::generateMipmapUsingImages(const gl::Context *context, } ANGLE_TRY(ensureRenderTarget(context)); } - else if (mRenderer->getFeatures().setDataFasterThanImageUpload.enabled && mTexStorage) + else if (couldUseSetData() && mTexStorage) { // When making mipmaps with the setData workaround enabled, the texture storage has // the image data already. For non-render-target storage, we have to pull it out into diff --git a/src/libANGLE/renderer/d3d/TextureD3D.h b/src/libANGLE/renderer/d3d/TextureD3D.h index 8e89c3e022..42764add11 100644 --- a/src/libANGLE/renderer/d3d/TextureD3D.h +++ b/src/libANGLE/renderer/d3d/TextureD3D.h @@ -224,6 +224,7 @@ class TextureD3D : public TextureImpl, public angle::ObserverInterface virtual angle::Result updateStorage(const gl::Context *context) = 0; + bool couldUseSetData() const; bool shouldUseSetData(const ImageD3D *image) const; angle::Result generateMipmapUsingImages(const gl::Context *context, const GLuint maxLevel); diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp index 4de7ba5c3d..b6c796dfaf 100644 --- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp @@ -2480,8 +2480,10 @@ void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps, isIntel && capsVersion >= angle::VersionTriple(16, 0, 0) && capsVersion < angle::VersionTriple(16, 4815, 0)); - // Haswell/Ivybridge drivers occasionally corrupt (small?) (vertex?) texture data uploads. - ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, + // Haswell drivers occasionally corrupt (small?) (vertex?) texture data uploads for 128bit + // formats. + ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, true); + ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats, !(isIvyBridge || isBroadwell || isHaswell)); ANGLE_FEATURE_CONDITION(features, disableB5G6R5Support, diff --git a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp index 52e9cdad65..aa53849f2a 100644 --- a/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp @@ -831,6 +831,7 @@ void InitializeFeatures(angle::FeaturesD3D *features, DWORD vendorID) { ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true); ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, false); + ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats, false); // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true); diff --git a/util/autogen/angle_features_autogen.cpp b/util/autogen/angle_features_autogen.cpp index 689d0af5ef..317e27e398 100644 --- a/util/autogen/angle_features_autogen.cpp +++ b/util/autogen/angle_features_autogen.cpp @@ -306,6 +306,7 @@ constexpr PackedEnumMap kFeatureNames = {{ {Feature::ScalarizeVecAndMatConstructorArgs, "scalarizeVecAndMatConstructorArgs"}, {Feature::SelectViewInGeometryShader, "selectViewInGeometryShader"}, {Feature::SetDataFasterThanImageUpload, "setDataFasterThanImageUpload"}, + {Feature::SetDataFasterThanImageUploadOn128bitFormats, "setDataFasterThanImageUploadOn128bitFormats"}, {Feature::SetPrimitiveRestartFixedIndexForDrawArrays, "setPrimitiveRestartFixedIndexForDrawArrays"}, {Feature::SetZeroLevelBeforeGenerateMipmap, "setZeroLevelBeforeGenerateMipmap"}, {Feature::ShiftInstancedArrayDataWithOffset, "shiftInstancedArrayDataWithOffset"}, diff --git a/util/autogen/angle_features_autogen.h b/util/autogen/angle_features_autogen.h index fa7afb6d8b..2627f9652d 100644 --- a/util/autogen/angle_features_autogen.h +++ b/util/autogen/angle_features_autogen.h @@ -306,6 +306,7 @@ enum class Feature ScalarizeVecAndMatConstructorArgs, SelectViewInGeometryShader, SetDataFasterThanImageUpload, + SetDataFasterThanImageUploadOn128bitFormats, SetPrimitiveRestartFixedIndexForDrawArrays, SetZeroLevelBeforeGenerateMipmap, ShiftInstancedArrayDataWithOffset, -- 2.54.0