[dawn][wire] Removes InjectDevice.
- Updated SampleUtils to use WireHelper.
- Added swap chain utility function in WireHelper.
Change-Id: Ic830d4251f48cc3ae57d129040965aa8f3fb8b5b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/175784
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/generator/templates/mock_api.cpp b/generator/templates/mock_api.cpp
index d01b443..b66b27e 100644
--- a/generator/templates/mock_api.cpp
+++ b/generator/templates/mock_api.cpp
@@ -65,7 +65,11 @@
{% for type in by_category["structure"] if type.has_free_members_function %}
table->{{as_varName(type.name, Name("free members"))}} = []({{as_cType(type.name)}} {{as_varName(type.name)}}) {
- dawn::WarningLog() << "No mock available for {{as_varName(type.name, Name('free members'))}}";
+ static bool calledOnce = false;
+ if (!calledOnce) {
+ calledOnce = true;
+ dawn::WarningLog() << "No mock available for {{as_varName(type.name, Name('free members'))}}";
+ }
};
{% endfor %}
}
diff --git a/include/dawn/wire/WireClient.h b/include/dawn/wire/WireClient.h
index fea95b6..a1e268a 100644
--- a/include/dawn/wire/WireClient.h
+++ b/include/dawn/wire/WireClient.h
@@ -80,7 +80,6 @@
ReservedTexture ReserveTexture(WGPUDevice device, const WGPUTextureDescriptor* descriptor);
ReservedSwapChain ReserveSwapChain(WGPUDevice device,
const WGPUSwapChainDescriptor* descriptor);
- ReservedDevice ReserveDevice(WGPUInstance instance);
ReservedInstance ReserveInstance(const WGPUInstanceDescriptor* descriptor = nullptr);
void ReclaimTextureReservation(const ReservedTexture& reservation);
diff --git a/include/dawn/wire/WireServer.h b/include/dawn/wire/WireServer.h
index 3738cab..1c67262 100644
--- a/include/dawn/wire/WireServer.h
+++ b/include/dawn/wire/WireServer.h
@@ -56,7 +56,6 @@
bool InjectTexture(WGPUTexture texture, const Handle& handle, const Handle& deviceHandle);
bool InjectSwapChain(WGPUSwapChain swapchain, const Handle& handle, const Handle& deviceHandle);
- bool InjectDevice(WGPUDevice device, const Handle& handle);
bool InjectInstance(WGPUInstance instance, const Handle& handle);
// Look up a device by (id, generation) pair. Returns nullptr if the generation
diff --git a/src/dawn/samples/SampleUtils.cpp b/src/dawn/samples/SampleUtils.cpp
index 844459f..6acb553 100644
--- a/src/dawn/samples/SampleUtils.cpp
+++ b/src/dawn/samples/SampleUtils.cpp
@@ -42,6 +42,7 @@
#include "dawn/dawn_proc.h"
#include "dawn/native/DawnNative.h"
#include "dawn/utils/TerribleCommandBuffer.h"
+#include "dawn/utils/WireHelper.h"
#include "dawn/wire/WireClient.h"
#include "dawn/wire/WireServer.h"
#include "webgpu/webgpu_glfw.h"
@@ -110,16 +111,14 @@
static std::vector<std::string> disableToggles;
static CmdBufType cmdBufType = CmdBufType::Terrible;
-static std::unique_ptr<dawn::native::Instance> instance;
+static std::unique_ptr<dawn::native::Instance> backendInstance;
+static std::unique_ptr<dawn::utils::WireHelper> wireHelper;
+static dawn::native::Adapter backendAdapter;
+static WGPUDevice backendDevice;
static wgpu::SwapChain swapChain;
static GLFWwindow* window = nullptr;
-static dawn::wire::WireServer* wireServer = nullptr;
-static dawn::wire::WireClient* wireClient = nullptr;
-static dawn::utils::TerribleCommandBuffer* c2sBuf = nullptr;
-static dawn::utils::TerribleCommandBuffer* s2cBuf = nullptr;
-
static constexpr uint32_t kWidth = 640;
static constexpr uint32_t kHeight = 480;
@@ -144,59 +143,107 @@
WGPUInstanceDescriptor instanceDescriptor{};
instanceDescriptor.features.timedWaitAnyEnable = true;
- instance = std::make_unique<dawn::native::Instance>(&instanceDescriptor);
+ backendInstance = std::make_unique<dawn::native::Instance>(&instanceDescriptor);
- wgpu::RequestAdapterOptions options = {};
- options.backendType = backendType;
-
- // Get an adapter for the backend to use, and create the device.
- auto adapters = instance->EnumerateAdapters(&options);
- wgpu::DawnAdapterPropertiesPowerPreference power_props{};
- wgpu::AdapterProperties adapterProperties{};
- adapterProperties.nextInChain = &power_props;
- // Find the first adapter which satisfies the adapterType requirement.
- auto isAdapterType = [&adapterProperties](const auto& adapter) -> bool {
- // picks the first adapter when adapterType is unknown.
- if (adapterType == wgpu::AdapterType::Unknown) {
- return true;
- }
- adapter.GetProperties(&adapterProperties);
- return adapterProperties.adapterType == adapterType;
- };
- auto preferredAdapter = std::find_if(adapters.begin(), adapters.end(), isAdapterType);
- if (preferredAdapter == adapters.end()) {
- fprintf(stderr, "Failed to find an adapter! Please try another adapter type.\n");
- return wgpu::Device();
- }
-
- std::vector<const char*> enableToggleNames;
- std::vector<const char*> disabledToggleNames;
- for (const std::string& toggle : enableToggles) {
- enableToggleNames.push_back(toggle.c_str());
- }
-
- for (const std::string& toggle : disableToggles) {
- disabledToggleNames.push_back(toggle.c_str());
- }
- WGPUDawnTogglesDescriptor toggles;
- toggles.chain.sType = WGPUSType_DawnTogglesDescriptor;
- toggles.chain.next = nullptr;
- toggles.enabledToggles = enableToggleNames.data();
- toggles.enabledToggleCount = enableToggleNames.size();
- toggles.disabledToggles = disabledToggleNames.data();
- toggles.disabledToggleCount = disabledToggleNames.size();
-
- WGPUDeviceDescriptor deviceDesc = {};
- deviceDesc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&toggles);
-
- WGPUDevice backendDevice = preferredAdapter->CreateDevice(&deviceDesc);
+ // Set up native proc tables to override the behavior given command-line flags.
DawnProcTable backendProcs = dawn::native::GetProcs();
+ backendProcs.instanceRequestAdapter = [](WGPUInstance, const WGPURequestAdapterOptions*,
+ WGPURequestAdapterCallback callback, void* userdata) {
+ wgpu::RequestAdapterOptions options = {};
+ auto adapters = backendInstance->EnumerateAdapters(&options);
+ wgpu::DawnAdapterPropertiesPowerPreference power_props{};
+ wgpu::AdapterProperties adapterProperties{};
+ adapterProperties.nextInChain = &power_props;
+ // Find the first adapter which satisfies the adapterType requirement.
+ auto isAdapterType = [&adapterProperties](const auto& adapter) -> bool {
+ // picks the first adapter when adapterType is unknown.
+ if (adapterType == wgpu::AdapterType::Unknown) {
+ return true;
+ }
+ adapter.GetProperties(&adapterProperties);
+ return adapterProperties.adapterType == adapterType;
+ };
+ auto preferredAdapter = std::find_if(adapters.begin(), adapters.end(), isAdapterType);
+
+ if (preferredAdapter != adapters.end()) {
+ backendAdapter = *preferredAdapter;
+ WGPUAdapter cAdapter = preferredAdapter->Get();
+ dawn::native::GetProcs().adapterReference(cAdapter);
+ callback(WGPURequestAdapterStatus_Success, cAdapter, nullptr, userdata);
+ } else {
+ callback(WGPURequestAdapterStatus_Error, nullptr,
+ "Failed to find an adapter! Please try another adapter type.\n", userdata);
+ }
+ };
+ backendProcs.adapterRequestDevice = [](WGPUAdapter, const WGPUDeviceDescriptor*,
+ WGPURequestDeviceCallback callback, void* userdata) {
+ std::vector<const char*> enableToggleNames;
+ std::vector<const char*> disabledToggleNames;
+ for (const std::string& toggle : enableToggles) {
+ enableToggleNames.push_back(toggle.c_str());
+ }
+
+ for (const std::string& toggle : disableToggles) {
+ disabledToggleNames.push_back(toggle.c_str());
+ }
+ WGPUDawnTogglesDescriptor toggles;
+ toggles.chain.sType = WGPUSType_DawnTogglesDescriptor;
+ toggles.chain.next = nullptr;
+ toggles.enabledToggles = enableToggleNames.data();
+ toggles.enabledToggleCount = enableToggleNames.size();
+ toggles.disabledToggles = disabledToggleNames.data();
+ toggles.disabledToggleCount = disabledToggleNames.size();
+
+ WGPUDeviceDescriptor deviceDesc = {};
+ deviceDesc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&toggles);
+ backendDevice = backendAdapter.CreateDevice(&deviceDesc);
+ if (backendDevice != nullptr) {
+ callback(WGPURequestDeviceStatus_Success, backendDevice, nullptr, userdata);
+ } else {
+ callback(WGPURequestDeviceStatus_Error, nullptr, "Failed to create a device!\n",
+ userdata);
+ }
+ };
+
+ wireHelper = dawn::utils::CreateWireHelper(backendProcs, cmdBufType == CmdBufType::Terrible);
+ wgpu::Instance instance = wireHelper->RegisterInstance(backendInstance->Get());
+
+ wgpu::Adapter adapter = nullptr;
+ instance.RequestAdapter(
+ nullptr,
+ [](WGPURequestAdapterStatus, WGPUAdapter cAdapter, const char* message, void* userdata) {
+ if (message != nullptr) {
+ fprintf(stderr, "%s", message);
+ return;
+ }
+ *static_cast<wgpu::Adapter*>(userdata) = wgpu::Adapter::Acquire(cAdapter);
+ },
+ &adapter);
+ DoFlush();
+ DAWN_ASSERT(adapter != nullptr);
+
+ wgpu::Device device = nullptr;
+ adapter.RequestDevice(
+ nullptr,
+ [](WGPURequestDeviceStatus, WGPUDevice cDevice, const char* message, void* userdata) {
+ if (message != nullptr) {
+ fprintf(stderr, "%s", message);
+ return;
+ }
+ *static_cast<wgpu::Device*>(userdata) = wgpu::Device::Acquire(cDevice);
+ },
+ &device);
+ DoFlush();
+ DAWN_ASSERT(device != nullptr);
+ device.SetUncapturedErrorCallback(PrintDeviceError, nullptr);
+ device.SetDeviceLostCallback(DeviceLostCallback, nullptr);
+ device.SetLoggingCallback(DeviceLogCallback, nullptr);
// Create the swapchain
auto surfaceChainedDesc = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window);
WGPUSurfaceDescriptor surfaceDesc;
surfaceDesc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(surfaceChainedDesc.get());
- WGPUSurface surface = backendProcs.instanceCreateSurface(instance->Get(), &surfaceDesc);
+ WGPUSurface surface = backendProcs.instanceCreateSurface(backendInstance->Get(), &surfaceDesc);
WGPUSwapChainDescriptor swapChainDesc = {};
swapChainDesc.usage = WGPUTextureUsage_RenderAttachment;
@@ -204,57 +251,9 @@
swapChainDesc.width = kWidth;
swapChainDesc.height = kHeight;
swapChainDesc.presentMode = WGPUPresentMode_Mailbox;
- WGPUSwapChain backendSwapChain =
- backendProcs.deviceCreateSwapChain(backendDevice, surface, &swapChainDesc);
+ swapChain = wireHelper->CreateSwapChain(surface, backendDevice, device.Get(), &swapChainDesc);
- // Choose whether to use the backend procs and devices/swapchains directly, or set up the wire.
- WGPUDevice cDevice = nullptr;
- DawnProcTable procs;
-
- switch (cmdBufType) {
- case CmdBufType::None:
- procs = backendProcs;
- cDevice = backendDevice;
- swapChain = wgpu::SwapChain::Acquire(backendSwapChain);
- break;
-
- case CmdBufType::Terrible: {
- c2sBuf = new dawn::utils::TerribleCommandBuffer();
- s2cBuf = new dawn::utils::TerribleCommandBuffer();
-
- dawn::wire::WireServerDescriptor serverDesc = {};
- serverDesc.procs = &backendProcs;
- serverDesc.serializer = s2cBuf;
-
- wireServer = new dawn::wire::WireServer(serverDesc);
- c2sBuf->SetHandler(wireServer);
-
- dawn::wire::WireClientDescriptor clientDesc = {};
- clientDesc.serializer = c2sBuf;
-
- wireClient = new dawn::wire::WireClient(clientDesc);
- procs = dawn::wire::client::GetProcs();
- s2cBuf->SetHandler(wireClient);
-
- auto reservedInstance = wireClient->ReserveInstance();
- wireServer->InjectInstance(instance->Get(), reservedInstance.handle);
-
- auto reservedDevice = wireClient->ReserveDevice(reservedInstance.instance);
- wireServer->InjectDevice(backendDevice, reservedDevice.handle);
- cDevice = reservedDevice.device;
-
- auto reservedSwapChain = wireClient->ReserveSwapChain(cDevice, &swapChainDesc);
- wireServer->InjectSwapChain(backendSwapChain, reservedSwapChain.handle,
- reservedSwapChain.deviceHandle);
- swapChain = wgpu::SwapChain::Acquire(reservedSwapChain.swapchain);
- } break;
- }
-
- dawnProcSetProcs(&procs);
- procs.deviceSetUncapturedErrorCallback(cDevice, PrintDeviceError, nullptr);
- procs.deviceSetDeviceLostCallback(cDevice, DeviceLostCallback, nullptr);
- procs.deviceSetLoggingCallback(cDevice, DeviceLogCallback, nullptr);
- return wgpu::Device::Acquire(cDevice);
+ return device;
}
wgpu::TextureFormat GetPreferredSwapChainTextureFormat() {
@@ -423,8 +422,8 @@
void DoFlush() {
if (cmdBufType == CmdBufType::Terrible) {
- bool c2sSuccess = c2sBuf->Flush();
- bool s2cSuccess = s2cBuf->Flush();
+ bool c2sSuccess = wireHelper->FlushClient();
+ bool s2cSuccess = wireHelper->FlushServer();
DAWN_ASSERT(c2sSuccess && s2cSuccess);
}
@@ -440,5 +439,5 @@
}
void ProcessEvents() {
- dawn::native::InstanceProcessEvents(instance->Get());
+ dawn::native::InstanceProcessEvents(backendInstance->Get());
}
diff --git a/src/dawn/tests/BUILD.gn b/src/dawn/tests/BUILD.gn
index 05fe619..35cc1c5 100644
--- a/src/dawn/tests/BUILD.gn
+++ b/src/dawn/tests/BUILD.gn
@@ -435,7 +435,6 @@
"unittests/wire/WireExtensionTests.cpp",
"unittests/wire/WireFutureTest.cpp",
"unittests/wire/WireFutureTest.h",
- "unittests/wire/WireInjectDeviceTests.cpp",
"unittests/wire/WireInjectInstanceTests.cpp",
"unittests/wire/WireInjectSwapChainTests.cpp",
"unittests/wire/WireInjectTextureTests.cpp",
diff --git a/src/dawn/tests/unittests/GetProcAddressTests.cpp b/src/dawn/tests/unittests/GetProcAddressTests.cpp
index 1f8dabc..b6c3b85 100644
--- a/src/dawn/tests/unittests/GetProcAddressTests.cpp
+++ b/src/dawn/tests/unittests/GetProcAddressTests.cpp
@@ -91,8 +91,11 @@
clientDesc.serializer = mC2sBuf.get();
mWireClient = std::make_unique<wire::WireClient>(clientDesc);
- mDevice = wgpu::Device::Acquire(
- mWireClient->ReserveDevice(ToAPI(mNativeInstance.Get())).device);
+ // Note that currently we are passing a null device since we do not actually use the
+ // device in determining the resulting proc addresses. If/when we actually care
+ // about features on the device to determine a proc address, this should be updated
+ // accordingly.
+ mDevice = nullptr;
mProcs = wire::client::GetProcs();
break;
}
diff --git a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
index f216372..20ce02c 100644
--- a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
@@ -64,61 +64,6 @@
void* userdata = nullptr) {
CallImpl(userdata, a.Get(), reinterpret_cast<WGPUDeviceDescriptor const*>(descriptor));
}
-
- // Bootstrap the tests and create a fake adapter.
- void SetUp() override {
- WireAdapterTestBase::SetUp();
-
- WGPURequestAdapterOptions options = {};
- MockCallback<WGPURequestAdapterCallback> cb;
- wgpuInstanceRequestAdapter(instance, &options, cb.Callback(), cb.MakeUserdata(this));
-
- // Expect the server to receive the message. Then, mock a fake reply.
- apiAdapter = api.GetNewAdapter();
- EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), NotNull(), NotNull()))
- .WillOnce(InvokeWithoutArgs([&] {
- EXPECT_CALL(api, AdapterHasFeature(apiAdapter, _)).WillRepeatedly(Return(false));
-
- EXPECT_CALL(api, AdapterGetProperties(apiAdapter, NotNull()))
- .WillOnce(WithArg<1>(Invoke([&](WGPUAdapterProperties* properties) {
- *properties = {};
- properties->vendorName = "";
- properties->architecture = "";
- properties->name = "";
- properties->driverDescription = "";
- })));
-
- EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull()))
- .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
- *limits = {};
- return true;
- })));
-
- EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
- .WillOnce(Return(0))
- .WillOnce(Return(0));
- api.CallInstanceRequestAdapterCallback(
- apiInstance, WGPURequestAdapterStatus_Success, apiAdapter, nullptr);
- }));
- FlushClient();
-
- // Expect the callback in the client.
- WGPUAdapter cAdapter;
- EXPECT_CALL(cb, Call(WGPURequestAdapterStatus_Success, NotNull(), nullptr, this))
- .WillOnce(SaveArg<1>(&cAdapter));
- FlushServer();
-
- EXPECT_NE(cAdapter, nullptr);
- adapter = wgpu::Adapter::Acquire(cAdapter);
- }
-
- void TearDown() override {
- adapter = nullptr;
- WireAdapterTestBase::TearDown();
- }
-
- WGPUAdapter apiAdapter;
- wgpu::Adapter adapter;
};
DAWN_INSTANTIATE_WIRE_FUTURE_TEST_P(WireAdapterTests);
diff --git a/src/dawn/tests/unittests/wire/WireDisconnectTests.cpp b/src/dawn/tests/unittests/wire/WireDisconnectTests.cpp
index 889b52f..8220400 100644
--- a/src/dawn/tests/unittests/wire/WireDisconnectTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireDisconnectTests.cpp
@@ -173,7 +173,7 @@
// Expect release on all objects created by the client. Note: the device
// should be deleted first because it may free its reference to the default queue
// on deletion.
- Sequence s1, s2, s3, s4;
+ Sequence s1, s2, s3, s4, s5;
EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(apiDevice, nullptr, nullptr))
.Times(1)
.InSequence(s1, s2);
@@ -183,15 +183,17 @@
EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(apiDevice, nullptr, nullptr))
.Times(1)
.InSequence(s1, s2);
- EXPECT_CALL(api, DeviceRelease(apiDevice)).Times(1).InSequence(s1, s2, s3, s4);
+ EXPECT_CALL(api, DeviceRelease(apiDevice)).Times(1).InSequence(s1, s2, s3, s4, s5);
EXPECT_CALL(api, QueueRelease(apiQueue)).Times(1).InSequence(s1);
EXPECT_CALL(api, CommandEncoderRelease(apiCommandEncoder)).Times(1).InSequence(s2);
EXPECT_CALL(api, SamplerRelease(apiSampler)).Times(1).InSequence(s3);
- EXPECT_CALL(api, InstanceRelease(apiInstance)).Times(1).InSequence(s4);
+ EXPECT_CALL(api, AdapterRelease(apiAdapter)).Times(1).InSequence(s4);
+ EXPECT_CALL(api, InstanceRelease(apiInstance)).Times(1).InSequence(s5);
FlushClient();
// Signal that we already released and cleared callbacks for |apiDevice|
DefaultApiDeviceWasReleased();
+ DefaultApiAdapterWasReleased();
}
} // anonymous namespace
diff --git a/src/dawn/tests/unittests/wire/WireInjectDeviceTests.cpp b/src/dawn/tests/unittests/wire/WireInjectDeviceTests.cpp
deleted file mode 100644
index b49348d..0000000
--- a/src/dawn/tests/unittests/wire/WireInjectDeviceTests.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2021 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "dawn/tests/unittests/wire/WireTest.h"
-
-#include "dawn/wire/WireClient.h"
-#include "dawn/wire/WireServer.h"
-
-namespace dawn::wire {
-namespace {
-
-using testing::_;
-using testing::Exactly;
-using testing::Mock;
-using testing::Return;
-
-class WireInjectDeviceTests : public WireTest {
- public:
- WireInjectDeviceTests() {}
- ~WireInjectDeviceTests() override = default;
-};
-
-// Test that reserving and injecting a device makes calls on the client object forward to the
-// server object correctly.
-TEST_F(WireInjectDeviceTests, CallAfterReserveInject) {
- auto reserved = GetWireClient()->ReserveDevice(instance);
-
- WGPUDevice serverDevice = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice, reserved.handle));
-
- WGPUBufferDescriptor bufferDesc = {};
- wgpuDeviceCreateBuffer(reserved.device, &bufferDesc);
- WGPUBuffer serverBuffer = api.GetNewBuffer();
- EXPECT_CALL(api, DeviceCreateBuffer(serverDevice, _)).WillOnce(Return(serverBuffer));
- FlushClient();
-
- // Called on shutdown.
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, nullptr, nullptr))
- .Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, nullptr, nullptr)).Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, nullptr, nullptr))
- .Times(Exactly(1));
-}
-
-// Test that reserve correctly returns different IDs each time.
-TEST_F(WireInjectDeviceTests, ReserveDifferentIDs) {
- auto reserved1 = GetWireClient()->ReserveDevice(instance);
- auto reserved2 = GetWireClient()->ReserveDevice(instance);
-
- ASSERT_NE(reserved1.handle.id, reserved2.handle.id);
- ASSERT_NE(reserved1.device, reserved2.device);
-}
-
-// Test that injecting the same id without a destroy first fails.
-TEST_F(WireInjectDeviceTests, InjectExistingID) {
- auto reserved = GetWireClient()->ReserveDevice(instance);
-
- WGPUDevice serverDevice = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice, reserved.handle));
-
- // ID already in use, call fails.
- ASSERT_FALSE(GetWireServer()->InjectDevice(serverDevice, reserved.handle));
-
- // Called on shutdown.
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, nullptr, nullptr))
- .Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, nullptr, nullptr)).Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, nullptr, nullptr))
- .Times(Exactly(1));
-}
-
-// Test that the server only borrows the device and does a single reference-release
-TEST_F(WireInjectDeviceTests, InjectedDeviceLifetime) {
- auto reserved = GetWireClient()->ReserveDevice(instance);
-
- // Injecting the device adds a reference
- WGPUDevice serverDevice = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice, reserved.handle));
-
- // Releasing the device removes a single reference and clears its error callbacks.
- wgpuDeviceRelease(reserved.device);
- EXPECT_CALL(api, DeviceRelease(serverDevice));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, nullptr, nullptr)).Times(1);
- FlushClient();
-
- // Deleting the server doesn't release a second reference.
- DeleteServer();
- Mock::VerifyAndClearExpectations(&api);
-}
-
-// Test that it is an error to get the primary queue of a device before it has been
-// injected on the server.
-TEST_F(WireInjectDeviceTests, GetQueueBeforeInject) {
- auto reserved = GetWireClient()->ReserveDevice(instance);
-
- wgpuDeviceGetQueue(reserved.device);
- FlushClient(false);
-}
-
-// Test that it is valid to get the primary queue of a device after it has been
-// injected on the server.
-TEST_F(WireInjectDeviceTests, GetQueueAfterInject) {
- auto reserved = GetWireClient()->ReserveDevice(instance);
-
- WGPUDevice serverDevice = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice, reserved.handle));
-
- wgpuDeviceGetQueue(reserved.device);
-
- WGPUQueue apiQueue = api.GetNewQueue();
- EXPECT_CALL(api, DeviceGetQueue(serverDevice)).WillOnce(Return(apiQueue));
- FlushClient();
-
- // Called on shutdown.
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice, nullptr, nullptr))
- .Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice, nullptr, nullptr)).Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice, nullptr, nullptr))
- .Times(Exactly(1));
-}
-
-// Test that the list of live devices can be reflected using GetDevice.
-TEST_F(WireInjectDeviceTests, ReflectLiveDevices) {
- // Reserve two devices.
- auto reserved1 = GetWireClient()->ReserveDevice(instance);
- auto reserved2 = GetWireClient()->ReserveDevice(instance);
-
- // Inject both devices.
-
- WGPUDevice serverDevice1 = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice1));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice1, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice1, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice1, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice1, reserved1.handle));
-
- WGPUDevice serverDevice2 = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice2));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice2, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice2, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice2, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice2, reserved2.handle));
-
- // Test that both devices can be reflected.
- ASSERT_EQ(serverDevice1,
- GetWireServer()->GetDevice(reserved1.handle.id, reserved1.handle.generation));
- ASSERT_EQ(serverDevice2,
- GetWireServer()->GetDevice(reserved2.handle.id, reserved2.handle.generation));
-
- // Release the first device
- wgpuDeviceRelease(reserved1.device);
- EXPECT_CALL(api, DeviceRelease(serverDevice1));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice1, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice1, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice1, nullptr, nullptr)).Times(1);
- FlushClient();
-
- // The first device should no longer reflect, but the second should
- ASSERT_EQ(nullptr,
- GetWireServer()->GetDevice(reserved1.handle.id, reserved1.handle.generation));
- ASSERT_EQ(serverDevice2,
- GetWireServer()->GetDevice(reserved2.handle.id, reserved2.handle.generation));
-
- // Called on shutdown.
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice2, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice2, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice2, nullptr, nullptr)).Times(1);
-}
-
-// This is a regression test where a second device reservation invalidated pointers into the
-// KnownObjects std::vector of devices. The fix was to store pointers to heap allocated
-// objects instead.
-TEST_F(WireInjectDeviceTests, TrackChildObjectsWithTwoReservedDevices) {
- // Reserve one device, inject it, and get the primary queue.
- auto reserved1 = GetWireClient()->ReserveDevice(instance);
-
- WGPUDevice serverDevice1 = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice1));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice1, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice1, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice1, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice1, reserved1.handle));
-
- WGPUCommandEncoder commandEncoder = wgpuDeviceCreateCommandEncoder(reserved1.device, nullptr);
-
- WGPUCommandEncoder serverCommandEncoder = api.GetNewCommandEncoder();
- EXPECT_CALL(api, DeviceCreateCommandEncoder(serverDevice1, _))
- .WillOnce(Return(serverCommandEncoder));
- FlushClient();
-
- // Reserve a second device, and inject it.
- auto reserved2 = GetWireClient()->ReserveDevice(instance);
-
- WGPUDevice serverDevice2 = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(serverDevice2));
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice2, _, _));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice2, _, _));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice2, _, _));
- ASSERT_TRUE(GetWireServer()->InjectDevice(serverDevice2, reserved2.handle));
-
- // Release the encoder. This should work without error because it stores a stable
- // pointer to its device's list of child objects. On destruction, it removes itself from the
- // list.
- wgpuCommandEncoderRelease(commandEncoder);
- EXPECT_CALL(api, CommandEncoderRelease(serverCommandEncoder));
- FlushClient();
-
- // Called on shutdown.
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice1, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice1, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice1, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(serverDevice2, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(serverDevice2, nullptr, nullptr)).Times(1);
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(serverDevice2, nullptr, nullptr)).Times(1);
-}
-
-// Test that a device reservation can be reclaimed. This is necessary to
-// avoid leaking ObjectIDs for reservations that are never injected.
-TEST_F(WireInjectDeviceTests, ReclaimDeviceReservation) {
- // Test that doing a reservation and full release is an error.
- {
- auto reserved = GetWireClient()->ReserveDevice(instance);
- wgpuDeviceRelease(reserved.device);
- FlushClient(false);
- }
-
- // Test that doing a reservation and then reclaiming it recycles the ID.
- {
- auto reserved1 = GetWireClient()->ReserveDevice(instance);
- GetWireClient()->ReclaimDeviceReservation(reserved1);
-
- auto reserved2 = GetWireClient()->ReserveDevice(instance);
-
- // The ID is the same, but the generation is still different.
- ASSERT_EQ(reserved1.handle.id, reserved2.handle.id);
- ASSERT_NE(reserved1.handle.generation, reserved2.handle.generation);
-
- // No errors should occur.
- FlushClient();
- }
-}
-
-} // anonymous namespace
-} // namespace dawn::wire
diff --git a/src/dawn/tests/unittests/wire/WireTest.cpp b/src/dawn/tests/unittests/wire/WireTest.cpp
index 42638c0..9ce777b 100644
--- a/src/dawn/tests/unittests/wire/WireTest.cpp
+++ b/src/dawn/tests/unittests/wire/WireTest.cpp
@@ -28,6 +28,7 @@
#include "dawn/tests/unittests/wire/WireTest.h"
#include "dawn/dawn_proc.h"
+#include "dawn/tests/MockCallback.h"
#include "dawn/utils/TerribleCommandBuffer.h"
#include "dawn/wire/WireClient.h"
#include "dawn/wire/WireServer.h"
@@ -35,8 +36,13 @@
using testing::_;
using testing::AnyNumber;
using testing::Exactly;
+using testing::Invoke;
using testing::Mock;
+using testing::MockCallback;
+using testing::NotNull;
using testing::Return;
+using testing::SaveArg;
+using testing::WithArg;
WireTest::WireTest() {}
@@ -53,11 +59,6 @@
void WireTest::SetUp() {
DawnProcTable mockProcs;
api.GetProcTable(&mockProcs);
-
- // This SetCallback call cannot be ignored because it is done as soon as we start the server
- EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(_, _, _)).Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetLoggingCallback(_, _, _)).Times(Exactly(1));
- EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(_, _, _)).Times(Exactly(1));
SetupIgnoredCallExpectations();
mS2cBuf = std::make_unique<dawn::utils::TerribleCommandBuffer>();
@@ -86,11 +87,79 @@
EXPECT_CALL(api, InstanceReference(apiInstance));
EXPECT_TRUE(GetWireServer()->InjectInstance(apiInstance, reservedInstance.handle));
- auto reservedDevice = mWireClient->ReserveDevice(instance);
- device = reservedDevice.device;
+ // Create the adapter for testing.
+ apiAdapter = api.GetNewAdapter();
+ WGPURequestAdapterOptions adapterOpts = {};
+ MockCallback<WGPURequestAdapterCallback> adapterCb;
+ wgpuInstanceRequestAdapter(instance, &adapterOpts, adapterCb.Callback(),
+ adapterCb.MakeUserdata(this));
+ EXPECT_CALL(api, OnInstanceRequestAdapter(apiInstance, NotNull(), NotNull(), NotNull()))
+ .WillOnce([&]() {
+ EXPECT_CALL(api, AdapterHasFeature(apiAdapter, _)).WillRepeatedly(Return(false));
+
+ EXPECT_CALL(api, AdapterGetProperties(apiAdapter, NotNull()))
+ .WillOnce(WithArg<1>(Invoke([&](WGPUAdapterProperties* properties) {
+ *properties = {};
+ properties->vendorName = "";
+ properties->architecture = "";
+ properties->name = "";
+ properties->driverDescription = "";
+ })));
+
+ EXPECT_CALL(api, AdapterGetLimits(apiAdapter, NotNull()))
+ .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
+ *limits = {};
+ return true;
+ })));
+
+ EXPECT_CALL(api, AdapterEnumerateFeatures(apiAdapter, nullptr))
+ .WillOnce(Return(0))
+ .WillOnce(Return(0));
+
+ api.CallInstanceRequestAdapterCallback(apiInstance, WGPURequestAdapterStatus_Success,
+ apiAdapter, nullptr);
+ });
+ FlushClient();
+ WGPUAdapter cAdapter = nullptr;
+ EXPECT_CALL(adapterCb, Call(WGPURequestAdapterStatus_Success, NotNull(), nullptr, this))
+ .WillOnce(SaveArg<1>(&cAdapter));
+ FlushServer();
+ EXPECT_NE(cAdapter, nullptr);
+ adapter = wgpu::Adapter::Acquire(cAdapter);
+
+ // Create the device for testing.
apiDevice = api.GetNewDevice();
- EXPECT_CALL(api, DeviceReference(apiDevice));
- mWireServer->InjectDevice(apiDevice, reservedDevice.handle);
+ WGPUDeviceDescriptor deviceDesc = {};
+ MockCallback<WGPURequestDeviceCallback> deviceCb;
+ wgpuAdapterRequestDevice(adapter.Get(), &deviceDesc, deviceCb.Callback(),
+ deviceCb.MakeUserdata(this));
+ EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), NotNull(), NotNull()))
+ .WillOnce([&]() {
+ // Set on device creation to forward callbacks to the client.
+ EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(apiDevice, NotNull(), NotNull()))
+ .Times(1);
+ EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, NotNull(), NotNull())).Times(1);
+ EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(apiDevice, NotNull(), NotNull()))
+ .Times(1);
+
+ EXPECT_CALL(api, DeviceGetLimits(apiDevice, NotNull()))
+ .WillOnce(WithArg<1>(Invoke([&](WGPUSupportedLimits* limits) {
+ *limits = {};
+ return true;
+ })));
+
+ EXPECT_CALL(api, DeviceEnumerateFeatures(apiDevice, nullptr))
+ .WillOnce(Return(0))
+ .WillOnce(Return(0));
+
+ api.CallAdapterRequestDeviceCallback(apiAdapter, WGPURequestDeviceStatus_Success,
+ apiDevice, nullptr);
+ });
+ FlushClient();
+ EXPECT_CALL(deviceCb, Call(WGPURequestDeviceStatus_Success, NotNull(), nullptr, this))
+ .WillOnce(SaveArg<1>(&device));
+ FlushServer();
+ EXPECT_NE(device, nullptr);
// The GetQueue is done on WireClient startup so we expect it now.
queue = wgpuDeviceGetQueue(device);
@@ -100,6 +169,14 @@
}
void WireTest::TearDown() {
+ // Drop last refs on objects.
+ if (apiAdapter) {
+ adapter = nullptr;
+ } else {
+ // Don't call release on the C++ wrapper if the C objects are already destroyed.
+ adapter.MoveToCHandle();
+ }
+
dawnProcSetProcs(nullptr);
// Derived classes should call the base TearDown() first. The client must
@@ -121,12 +198,18 @@
mWireServer = nullptr;
}
-// This should be called if |apiDevice| is no longer exists on the wire.
-// This signals that expectations in |TearDowb| shouldn't be added.
+// This should be called if |apiDevice| no longer exists on the wire.
+// This signals that expectations in |TearDown| shouldn't be added.
void WireTest::DefaultApiDeviceWasReleased() {
apiDevice = nullptr;
}
+// This should be called if |apiAdapter| no longer exists on the wire.
+// This signals that expectations in |TearDown| shouldn't be added.
+void WireTest::DefaultApiAdapterWasReleased() {
+ apiAdapter = nullptr;
+}
+
void WireTest::FlushClient(bool success) {
ASSERT_EQ(mC2sBuf->Flush(), success);
@@ -149,6 +232,7 @@
void WireTest::DeleteServer() {
EXPECT_CALL(api, QueueRelease(apiQueue)).Times(1);
EXPECT_CALL(api, DeviceRelease(apiDevice)).Times(1);
+ EXPECT_CALL(api, AdapterRelease(apiAdapter)).Times(1);
EXPECT_CALL(api, InstanceRelease(apiInstance)).Times(1);
if (mWireServer) {
diff --git a/src/dawn/tests/unittests/wire/WireTest.h b/src/dawn/tests/unittests/wire/WireTest.h
index a45c651..7b4074b 100644
--- a/src/dawn/tests/unittests/wire/WireTest.h
+++ b/src/dawn/tests/unittests/wire/WireTest.h
@@ -34,6 +34,8 @@
#include "dawn/mock_webgpu.h"
#include "gtest/gtest.h"
+#include "webgpu/webgpu_cpp.h"
+
// Definition of a "Lambda predicate matcher" for GMock to allow checking deep structures
// are passed correctly by the wire.
@@ -143,14 +145,17 @@
void FlushServer(bool success = true);
void DefaultApiDeviceWasReleased();
+ void DefaultApiAdapterWasReleased();
testing::StrictMock<MockProcTable> api;
WGPUInstance instance;
WGPUInstance apiInstance;
- WGPUDevice apiDevice;
- WGPUQueue apiQueue;
+ wgpu::Adapter adapter;
+ WGPUAdapter apiAdapter;
WGPUDevice device;
+ WGPUDevice apiDevice;
WGPUQueue queue;
+ WGPUQueue apiQueue;
dawn::wire::WireServer* GetWireServer();
dawn::wire::WireClient* GetWireClient();
diff --git a/src/dawn/utils/WireHelper.cpp b/src/dawn/utils/WireHelper.cpp
index 13a0667..de72764 100644
--- a/src/dawn/utils/WireHelper.cpp
+++ b/src/dawn/utils/WireHelper.cpp
@@ -95,7 +95,9 @@
class WireHelperDirect : public WireHelper {
public:
- explicit WireHelperDirect(const DawnProcTable& procs) { dawnProcSetProcs(&procs); }
+ explicit WireHelperDirect(const DawnProcTable& procs) : mProcs(procs) {
+ dawnProcSetProcs(&procs);
+ }
wgpu::Instance RegisterInstance(WGPUInstance backendInstance,
const WGPUInstanceDescriptor* wireDesc) override {
@@ -103,16 +105,30 @@
return wgpu::Instance(backendInstance);
}
+ wgpu::SwapChain CreateSwapChain(WGPUSurface backendSurface,
+ WGPUDevice backendDevice,
+ WGPUDevice apiDevice,
+ const WGPUSwapChainDescriptor* descriptor) override {
+ DAWN_ASSERT(backendDevice == apiDevice);
+ WGPUSwapChain cSwapChain =
+ mProcs.deviceCreateSwapChain(backendDevice, backendSurface, descriptor);
+ return wgpu::SwapChain::Acquire(cSwapChain);
+ }
+
void BeginWireTrace(const char* name) override {}
bool FlushClient() override { return true; }
bool FlushServer() override { return true; }
+
+ private:
+ const DawnProcTable& mProcs;
};
class WireHelperProxy : public WireHelper {
public:
- explicit WireHelperProxy(const char* wireTraceDir, const DawnProcTable& procs) {
+ explicit WireHelperProxy(const char* wireTraceDir, const DawnProcTable& procs)
+ : mBackendProcs(procs) {
mC2sBuf = std::make_unique<dawn::utils::TerribleCommandBuffer>();
mS2cBuf = std::make_unique<dawn::utils::TerribleCommandBuffer>();
@@ -146,6 +162,19 @@
return wgpu::Instance::Acquire(reserved.instance);
}
+ wgpu::SwapChain CreateSwapChain(WGPUSurface backendSurface,
+ WGPUDevice backendDevice,
+ WGPUDevice apiDevice,
+ const WGPUSwapChainDescriptor* descriptor) override {
+ WGPUSwapChain cSwapChain =
+ mBackendProcs.deviceCreateSwapChain(backendDevice, backendSurface, descriptor);
+
+ auto reservation = mWireClient->ReserveSwapChain(apiDevice, descriptor);
+ mWireServer->InjectSwapChain(cSwapChain, reservation.handle, reservation.deviceHandle);
+
+ return wgpu::SwapChain::Acquire(reservation.swapchain);
+ }
+
void BeginWireTrace(const char* name) override {
if (mWireServerTraceLayer) {
return mWireServerTraceLayer->BeginWireTrace(name);
@@ -157,6 +186,7 @@
bool FlushServer() override { return mS2cBuf->Flush(); }
private:
+ const DawnProcTable& mBackendProcs;
std::unique_ptr<dawn::utils::TerribleCommandBuffer> mC2sBuf;
std::unique_ptr<dawn::utils::TerribleCommandBuffer> mS2cBuf;
std::unique_ptr<WireServerTraceLayer> mWireServerTraceLayer;
diff --git a/src/dawn/utils/WireHelper.h b/src/dawn/utils/WireHelper.h
index f39c63f..7c02388 100644
--- a/src/dawn/utils/WireHelper.h
+++ b/src/dawn/utils/WireHelper.h
@@ -59,6 +59,12 @@
const wgpu::InstanceDescriptor* nativeDesc = nullptr,
const wgpu::InstanceDescriptor* wireDesc = nullptr);
+ // Creates a swap chain given a native device and surface.
+ virtual wgpu::SwapChain CreateSwapChain(WGPUSurface backendSurface,
+ WGPUDevice backendDevice,
+ WGPUDevice apiDevice,
+ const WGPUSwapChainDescriptor* descriptor) = 0;
+
virtual void BeginWireTrace(const char* name) = 0;
virtual bool FlushClient() = 0;
diff --git a/src/dawn/wire/WireClient.cpp b/src/dawn/wire/WireClient.cpp
index 313073f..aa15aa2 100644
--- a/src/dawn/wire/WireClient.cpp
+++ b/src/dawn/wire/WireClient.cpp
@@ -51,10 +51,6 @@
return mImpl->ReserveSwapChain(device, descriptor);
}
-ReservedDevice WireClient::ReserveDevice(WGPUInstance instance) {
- return mImpl->ReserveDevice(instance);
-}
-
ReservedInstance WireClient::ReserveInstance(const WGPUInstanceDescriptor* descriptor) {
return mImpl->ReserveInstance(descriptor);
}
diff --git a/src/dawn/wire/WireServer.cpp b/src/dawn/wire/WireServer.cpp
index 6f299d8..02067d6 100644
--- a/src/dawn/wire/WireServer.cpp
+++ b/src/dawn/wire/WireServer.cpp
@@ -55,10 +55,6 @@
return mImpl->InjectSwapChain(swapchain, handle, deviceHandle) == WireResult::Success;
}
-bool WireServer::InjectDevice(WGPUDevice device, const Handle& handle) {
- return mImpl->InjectDevice(device, handle) == WireResult::Success;
-}
-
bool WireServer::InjectInstance(WGPUInstance instance, const Handle& handle) {
return mImpl->InjectInstance(instance, handle) == WireResult::Success;
}
diff --git a/src/dawn/wire/client/Client.cpp b/src/dawn/wire/client/Client.cpp
index 435246c..2bc76dc 100644
--- a/src/dawn/wire/client/Client.cpp
+++ b/src/dawn/wire/client/Client.cpp
@@ -115,15 +115,6 @@
return result;
}
-ReservedDevice Client::ReserveDevice(WGPUInstance instance) {
- Device* device = Make<Device>(FromAPI(instance)->GetEventManagerHandle(), nullptr);
-
- ReservedDevice result;
- result.device = ToAPI(device);
- result.handle = device->GetWireHandle();
- return result;
-}
-
ReservedInstance Client::ReserveInstance(const WGPUInstanceDescriptor* descriptor) {
Instance* instance = Make<Instance>();
diff --git a/src/dawn/wire/client/Client.h b/src/dawn/wire/client/Client.h
index 3c15b81..0d57c02 100644
--- a/src/dawn/wire/client/Client.h
+++ b/src/dawn/wire/client/Client.h
@@ -90,7 +90,6 @@
ReservedTexture ReserveTexture(WGPUDevice device, const WGPUTextureDescriptor* descriptor);
ReservedSwapChain ReserveSwapChain(WGPUDevice device,
const WGPUSwapChainDescriptor* descriptor);
- ReservedDevice ReserveDevice(WGPUInstance instance);
ReservedInstance ReserveInstance(const WGPUInstanceDescriptor* descriptor);
void ReclaimTextureReservation(const ReservedTexture& reservation);
diff --git a/src/dawn/wire/server/Server.cpp b/src/dawn/wire/server/Server.cpp
index 3ca111e..34cddbf 100644
--- a/src/dawn/wire/server/Server.cpp
+++ b/src/dawn/wire/server/Server.cpp
@@ -104,26 +104,6 @@
return WireResult::Success;
}
-WireResult Server::InjectDevice(WGPUDevice device, const Handle& handle) {
- DAWN_ASSERT(device != nullptr);
- Known<WGPUDevice> data;
- WIRE_TRY(DeviceObjects().Allocate(&data, handle));
-
- data->handle = device;
- data->generation = handle.generation;
- data->state = AllocationState::Allocated;
- data->info->server = this;
- data->info->self = data.AsHandle();
-
- // The device is externally owned so it shouldn't be destroyed when we receive a destroy
- // message from the client. Add a reference to counterbalance the eventual release.
- mProcs.deviceReference(device);
-
- // Set callbacks to forward errors to the client.
- SetForwardingDeviceCallbacks(data);
- return WireResult::Success;
-}
-
WireResult Server::InjectInstance(WGPUInstance instance, const Handle& handle) {
DAWN_ASSERT(instance != nullptr);
Known<WGPUInstance> data;
diff --git a/src/dawn/wire/server/Server.h b/src/dawn/wire/server/Server.h
index 5930e0a..ccd0a72 100644
--- a/src/dawn/wire/server/Server.h
+++ b/src/dawn/wire/server/Server.h
@@ -176,7 +176,6 @@
WireResult InjectSwapChain(WGPUSwapChain swapchain,
const Handle& handle,
const Handle& deviceHandle);
- WireResult InjectDevice(WGPUDevice device, const Handle& handle);
WireResult InjectInstance(WGPUInstance instance, const Handle& handle);
WGPUDevice GetDevice(uint32_t id, uint32_t generation);