1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "FenceD3D11.h"
13 #include "mozilla/gfx/Logging.h"
18 MOZ_RUNINIT RefPtr
<ID3D11Device
> mDevice
;
21 RefPtr
<FenceD3D11
> FenceD3D11::Create(ID3D11Device
* aDevice
) {
28 RefPtr
<ID3D11Device5
> d3d11_5
;
30 aDevice
->QueryInterface(__uuidof(ID3D11Device5
), getter_AddRefs(d3d11_5
));
32 gfxCriticalNoteOnce
<< "Failed to get ID3D11Device5: " << gfx::hexa(hr
);
36 RefPtr
<ID3D11Fence
> fenceD3D11
;
37 d3d11_5
->CreateFence(0, D3D11_FENCE_FLAG_SHARED
,
38 IID_PPV_ARGS((ID3D11Fence
**)getter_AddRefs(fenceD3D11
)));
40 gfxCriticalNoteOnce
<< "Fence creation failed: " << gfx::hexa(hr
);
44 HANDLE sharedHandle
= nullptr;
45 hr
= fenceD3D11
->CreateSharedHandle(nullptr, GENERIC_ALL
, nullptr,
48 gfxCriticalNoteOnce
<< "Fence shared handle creation failed "
53 RefPtr
<gfx::FileHandleWrapper
> handle
=
54 new gfx::FileHandleWrapper(UniqueFileHandle(sharedHandle
));
55 RefPtr
<FenceD3D11
> fence
= new FenceD3D11(handle
);
56 fence
->mDevice
= aDevice
;
57 fence
->mSignalFence
= fenceD3D11
;
63 RefPtr
<FenceD3D11
> FenceD3D11::CreateFromHandle(
64 RefPtr
<gfx::FileHandleWrapper
> aHandle
) {
65 // Opening shared handle is deferred.
66 return new FenceD3D11(aHandle
);
70 bool FenceD3D11::IsSupported(ID3D11Device
* aDevice
) {
71 RefPtr
<ID3D11Device5
> d3d11_5
;
73 aDevice
->QueryInterface(__uuidof(ID3D11Device5
), getter_AddRefs(d3d11_5
));
80 FenceD3D11::FenceD3D11(RefPtr
<gfx::FileHandleWrapper
>& aHandle
)
85 FenceD3D11::~FenceD3D11() {}
87 gfx::FenceInfo
FenceD3D11::GetFenceInfo() const {
88 return gfx::FenceInfo(mHandle
, mFenceValue
);
91 bool FenceD3D11::IncrementAndSignal() {
93 MOZ_ASSERT(mSignalFence
);
95 if (!mDevice
|| !mSignalFence
) {
99 RefPtr
<ID3D11DeviceContext
> context
;
100 mDevice
->GetImmediateContext(getter_AddRefs(context
));
101 RefPtr
<ID3D11DeviceContext4
> context4
;
102 auto hr
= context
->QueryInterface(__uuidof(ID3D11DeviceContext4
),
103 getter_AddRefs(context4
));
105 gfxCriticalNoteOnce
<< "Failed to get D3D11DeviceContext4: "
110 hr
= context4
->Signal(mSignalFence
, mFenceValue
+ 1);
112 gfxCriticalNoteOnce
<< "Signal fence failed: " << gfx::hexa(hr
);
120 void FenceD3D11::Update(uint64_t aFenceValue
) {
121 MOZ_ASSERT(!mDevice
);
122 MOZ_ASSERT(!mSignalFence
);
124 if (mFenceValue
> aFenceValue
) {
125 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
128 mFenceValue
= aFenceValue
;
131 bool FenceD3D11::Wait(ID3D11Device
* aDevice
) {
138 // Skip wait if passed device is the same as signaling device.
139 if (mDevice
== aDevice
) {
143 RefPtr
<ID3D11Fence
> fence
;
144 auto it
= mWaitFenceMap
.find(aDevice
);
145 if (it
== mWaitFenceMap
.end()) {
146 RefPtr
<ID3D11Device5
> d3d11_5
;
147 auto hr
= aDevice
->QueryInterface(__uuidof(ID3D11Device5
),
148 getter_AddRefs(d3d11_5
));
150 gfxCriticalNoteOnce
<< "Failed to get ID3D11Device5: " << gfx::hexa(hr
);
153 hr
= d3d11_5
->OpenSharedFence(mHandle
->GetHandle(), __uuidof(ID3D11Fence
),
154 (void**)(ID3D11Fence
**)getter_AddRefs(fence
));
156 gfxCriticalNoteOnce
<< "Opening fence shared handle failed "
160 mWaitFenceMap
.emplace(aDevice
, fence
);
166 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
170 RefPtr
<ID3D11DeviceContext
> context
;
171 aDevice
->GetImmediateContext(getter_AddRefs(context
));
172 RefPtr
<ID3D11DeviceContext4
> context4
;
173 auto hr
= context
->QueryInterface(__uuidof(ID3D11DeviceContext4
),
174 getter_AddRefs(context4
));
176 gfxCriticalNoteOnce
<< "Failed to get D3D11DeviceContext4: "
180 hr
= context4
->Wait(fence
, mFenceValue
);
182 gfxCriticalNoteOnce
<< "Failed to wait fence: " << gfx::hexa(hr
);
189 } // namespace layers
190 } // namespace mozilla