Bug 1919083 - [ci] Enable os-integration variant for more suites, r=jmaher
[gecko.git] / gfx / layers / d3d11 / FenceD3D11.cpp
blobcb97c8318ce6a4fe1ff88154e0323cf7c58a40b4
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"
9 #include <d3d11.h>
10 #include <d3d11_3.h>
11 #include <d3d11_4.h>
13 #include "mozilla/gfx/Logging.h"
15 namespace mozilla {
16 namespace layers {
18 MOZ_RUNINIT RefPtr<ID3D11Device> mDevice;
20 /* static */
21 RefPtr<FenceD3D11> FenceD3D11::Create(ID3D11Device* aDevice) {
22 MOZ_ASSERT(aDevice);
24 if (!aDevice) {
25 return nullptr;
28 RefPtr<ID3D11Device5> d3d11_5;
29 auto hr =
30 aDevice->QueryInterface(__uuidof(ID3D11Device5), getter_AddRefs(d3d11_5));
31 if (FAILED(hr)) {
32 gfxCriticalNoteOnce << "Failed to get ID3D11Device5: " << gfx::hexa(hr);
33 return nullptr;
36 RefPtr<ID3D11Fence> fenceD3D11;
37 d3d11_5->CreateFence(0, D3D11_FENCE_FLAG_SHARED,
38 IID_PPV_ARGS((ID3D11Fence**)getter_AddRefs(fenceD3D11)));
39 if (FAILED(hr)) {
40 gfxCriticalNoteOnce << "Fence creation failed: " << gfx::hexa(hr);
41 return nullptr;
44 HANDLE sharedHandle = nullptr;
45 hr = fenceD3D11->CreateSharedHandle(nullptr, GENERIC_ALL, nullptr,
46 &sharedHandle);
47 if (FAILED(hr)) {
48 gfxCriticalNoteOnce << "Fence shared handle creation failed "
49 << gfx::hexa(hr);
50 return nullptr;
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;
59 return fence;
62 /* static */
63 RefPtr<FenceD3D11> FenceD3D11::CreateFromHandle(
64 RefPtr<gfx::FileHandleWrapper> aHandle) {
65 // Opening shared handle is deferred.
66 return new FenceD3D11(aHandle);
69 /* static */
70 bool FenceD3D11::IsSupported(ID3D11Device* aDevice) {
71 RefPtr<ID3D11Device5> d3d11_5;
72 auto hr =
73 aDevice->QueryInterface(__uuidof(ID3D11Device5), getter_AddRefs(d3d11_5));
74 if (FAILED(hr)) {
75 return false;
77 return true;
80 FenceD3D11::FenceD3D11(RefPtr<gfx::FileHandleWrapper>& aHandle)
81 : mHandle(aHandle) {
82 MOZ_ASSERT(mHandle);
85 FenceD3D11::~FenceD3D11() {}
87 gfx::FenceInfo FenceD3D11::GetFenceInfo() const {
88 return gfx::FenceInfo(mHandle, mFenceValue);
91 bool FenceD3D11::IncrementAndSignal() {
92 MOZ_ASSERT(mDevice);
93 MOZ_ASSERT(mSignalFence);
95 if (!mDevice || !mSignalFence) {
96 return false;
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));
104 if (FAILED(hr)) {
105 gfxCriticalNoteOnce << "Failed to get D3D11DeviceContext4: "
106 << gfx::hexa(hr);
107 return false;
110 hr = context4->Signal(mSignalFence, mFenceValue + 1);
111 if (FAILED(hr)) {
112 gfxCriticalNoteOnce << "Signal fence failed: " << gfx::hexa(hr);
113 return false;
116 mFenceValue++;
117 return true;
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");
126 return;
128 mFenceValue = aFenceValue;
131 bool FenceD3D11::Wait(ID3D11Device* aDevice) {
132 MOZ_ASSERT(aDevice);
134 if (!aDevice) {
135 return false;
138 // Skip wait if passed device is the same as signaling device.
139 if (mDevice == aDevice) {
140 return true;
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));
149 if (FAILED(hr)) {
150 gfxCriticalNoteOnce << "Failed to get ID3D11Device5: " << gfx::hexa(hr);
151 return false;
153 hr = d3d11_5->OpenSharedFence(mHandle->GetHandle(), __uuidof(ID3D11Fence),
154 (void**)(ID3D11Fence**)getter_AddRefs(fence));
155 if (FAILED(hr)) {
156 gfxCriticalNoteOnce << "Opening fence shared handle failed "
157 << gfx::hexa(hr);
158 return false;
160 mWaitFenceMap.emplace(aDevice, fence);
161 } else {
162 fence = it->second;
165 if (!fence) {
166 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
167 return false;
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));
175 if (FAILED(hr)) {
176 gfxCriticalNoteOnce << "Failed to get D3D11DeviceContext4: "
177 << gfx::hexa(hr);
178 return false;
180 hr = context4->Wait(fence, mFenceValue);
181 if (FAILED(hr)) {
182 gfxCriticalNoteOnce << "Failed to wait fence: " << gfx::hexa(hr);
183 return false;
186 return true;
189 } // namespace layers
190 } // namespace mozilla