From 1fc1753d4d4666cf6d6cadfaa1a436c1988ef6af Mon Sep 17 00:00:00 2001 From: trav90 Date: Tue, 28 Nov 2023 14:38:32 -0600 Subject: [PATCH] Issue #2393 - Part 1 - Allow client side uploads on Intel hardware --- gfx/layers/IMFYCbCrImage.cpp | 53 +++++++++++++++++++++++++++------- gfx/thebes/DeviceManagerDx.cpp | 2 +- gfx/thebes/gfxPrefs.h | 3 +- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/gfx/layers/IMFYCbCrImage.cpp b/gfx/layers/IMFYCbCrImage.cpp index 6740fdbe07..0f1ec5f295 100644 --- a/gfx/layers/IMFYCbCrImage.cpp +++ b/gfx/layers/IMFYCbCrImage.cpp @@ -253,6 +253,18 @@ IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) return nullptr; } + HRESULT hr; + RefPtr mt; + hr = device->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt)); + + if (FAILED(hr)) { + return nullptr; + } + + if (!mt->GetMultithreadProtected()) { + return nullptr; + } + if (mData.mYStride < 0 || mData.mCbCrStride < 0) { // D3D11 only supports unsigned stride values. return nullptr; @@ -268,29 +280,50 @@ IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) } RefPtr textureY; - D3D11_SUBRESOURCE_DATA yData = { mData.mYChannel, (UINT)mData.mYStride, 0 }; - HRESULT hr = device->CreateTexture2D(&newDesc, &yData, getter_AddRefs(textureY)); + hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr textureCb; - D3D11_SUBRESOURCE_DATA cbData = { mData.mCbChannel, (UINT)mData.mCbCrStride, 0 }; - hr = device->CreateTexture2D(&newDesc, &cbData, getter_AddRefs(textureCb)); + hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr textureCr; - D3D11_SUBRESOURCE_DATA crData = { mData.mCrChannel, (UINT)mData.mCbCrStride, 0 }; - hr = device->CreateTexture2D(&newDesc, &crData, getter_AddRefs(textureCr)); + hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); - // Even though the textures we created are meant to be protected by a keyed mutex, - // it appears that D3D doesn't include the initial memory upload within this - // synchronization. Add an empty lock/unlock pair since that appears to - // be sufficient to make sure we synchronize. + // The documentation here seems to suggest using the immediate mode context + // on more than one thread is not allowed: + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476891(v=vs.85).aspx + // The Debug Layer seems to imply it is though. When the ID3D10Multithread + // layer is on. The Enter/Leave of the critical section shouldn't even be + // required but were added for extra security. + { + AutoLockTexture lockY(textureY); AutoLockTexture lockCr(textureCr); + AutoLockTexture lockCb(textureCb); + + mt->Enter(); + + RefPtr ctx; + device->GetImmediateContext((ID3D11DeviceContext**)getter_AddRefs(ctx)); + + D3D11_BOX box; + box.front = box.top = box.left = 0; + box.back = 1; + box.right = mData.mYSize.width; + box.bottom = mData.mYSize.height; + ctx->UpdateSubresource(textureY, 0, &box, mData.mYChannel, mData.mYStride, 0); + + box.right = mData.mCbCrSize.width; + box.bottom = mData.mCbCrSize.height; + ctx->UpdateSubresource(textureCb, 0, &box, mData.mCbChannel, mData.mCbCrStride, 0); + ctx->UpdateSubresource(textureCr, 0, &box, mData.mCrChannel, mData.mCbCrStride, 0); + + mt->Leave(); } mTextureClient = TextureClient::CreateWithData( diff --git a/gfx/thebes/DeviceManagerDx.cpp b/gfx/thebes/DeviceManagerDx.cpp index 5f505f88ba..a55d1a72a0 100644 --- a/gfx/thebes/DeviceManagerDx.cpp +++ b/gfx/thebes/DeviceManagerDx.cpp @@ -781,7 +781,7 @@ DeviceManagerDx::CanInitializeKeyedMutexTextures() } // Disable this on all Intel devices because of crashes. // See bug 1292923. - return mDeviceStatus->adapter().VendorId != 0x8086; + return (mDeviceStatus->adapter().VendorId != 0x8086 || gfxPrefs::Direct3D11AllowIntelMutex()); } bool diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index fd5946cb2a..382cc0ee20 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -376,6 +376,7 @@ private: DECL_GFX_PREF(Once, "gfx.direct2d.disabled", Direct2DDisabled, bool, false); DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled", Direct2DForceEnabled, bool, false); DECL_GFX_PREF(Live, "gfx.direct3d11.reuse-decoder-device", Direct3D11ReuseDecoderDevice, int32_t, -1); + DECL_GFX_PREF(Live, "gfx.direct3d11.allow-intel-mutex", Direct3D11AllowIntelMutex, bool, true); DECL_GFX_PREF(Live, "gfx.draw-color-bars", CompositorDrawColorBars, bool, false); DECL_GFX_PREF(Once, "gfx.e10s.hide-plugins-for-scroll", HidePluginsForScroll, bool, true); DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels", GrallocFenceWithReadPixels, bool, false); @@ -601,7 +602,7 @@ private: DECL_GFX_PREF(Live, "webgl.lose-context-on-memory-pressure", WebGLLoseContextOnMemoryPressure, bool, false); DECL_GFX_PREF(Live, "webgl.max-warnings-per-context", WebGLMaxWarningsPerContext, uint32_t, 32); DECL_GFX_PREF(Live, "webgl.max-size-per-texture-mb", WebGLMaxSizePerTextureMB, uint32_t, 1024); - DECL_GFX_PREF(Live, "webgl.max-vert-ids-per-draw", WebglMaxVertIDsPerDraw, uint32_t, 30*1000*1000); + DECL_GFX_PREF(Live, "webgl.max-vert-ids-per-draw", WebglMaxVertIDsPerDraw, uint32_t, 30*1000*1000); DECL_GFX_PREF(Live, "webgl.min_capability_mode", WebGLMinCapabilityMode, bool, false); DECL_GFX_PREF(Live, "webgl.msaa-force", WebGLForceMSAA, bool, false); DECL_GFX_PREF(Live, "webgl.prefer-16bpp", WebGLPrefer16bpp, bool, false);