Special-case GetDefaultQueue in the wire

This makes it so calling GetDefaultQueue always returns the same
object. It required updating various WireTests to account for the
additional wire calls.

Bug: dawn:22

Change-Id: I8c74374b7c732b8bb7d0490bbc740dee0d2dface
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/19726
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Corentin Wallez 2020-04-17 17:09:07 +00:00 committed by Commit Bot service account
parent 8a437947a8
commit f93791ab62
11 changed files with 79 additions and 31 deletions

View File

@ -101,6 +101,7 @@
"BufferUnmap", "BufferUnmap",
"DeviceCreateBuffer", "DeviceCreateBuffer",
"DeviceCreateBufferMapped", "DeviceCreateBufferMapped",
"DeviceGetDefaultQueue",
"DevicePushErrorScope", "DevicePushErrorScope",
"QueueCreateFence", "QueueCreateFence",
"QueueSignal" "QueueSignal"

View File

@ -370,6 +370,11 @@ namespace dawn_wire { namespace client {
void ClientDeviceRelease(WGPUDevice) { void ClientDeviceRelease(WGPUDevice) {
} }
WGPUQueue ClientHandwrittenDeviceGetDefaultQueue(WGPUDevice cSelf) {
Device* device = reinterpret_cast<Device*>(cSelf);
return device->GetDefaultQueue();
}
void ClientHandwrittenDeviceSetUncapturedErrorCallback(WGPUDevice cSelf, void ClientHandwrittenDeviceSetUncapturedErrorCallback(WGPUDevice cSelf,
WGPUErrorCallback callback, WGPUErrorCallback callback,
void* userdata) { void* userdata) {

View File

@ -21,7 +21,6 @@ namespace dawn_wire { namespace client {
Client::Client(CommandSerializer* serializer, MemoryTransferService* memoryTransferService) Client::Client(CommandSerializer* serializer, MemoryTransferService* memoryTransferService)
: ClientBase(), : ClientBase(),
mDevice(DeviceAllocator().New(this)->object.get()),
mSerializer(serializer), mSerializer(serializer),
mMemoryTransferService(memoryTransferService) { mMemoryTransferService(memoryTransferService) {
if (mMemoryTransferService == nullptr) { if (mMemoryTransferService == nullptr) {
@ -29,6 +28,8 @@ namespace dawn_wire { namespace client {
mOwnedMemoryTransferService = CreateInlineMemoryTransferService(); mOwnedMemoryTransferService = CreateInlineMemoryTransferService();
mMemoryTransferService = mOwnedMemoryTransferService.get(); mMemoryTransferService = mOwnedMemoryTransferService.get();
} }
mDevice = DeviceAllocator().New(this)->object.get();
} }
Client::~Client() { Client::~Client() {

View File

@ -16,20 +16,46 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "dawn_wire/WireCmd_autogen.h" #include "dawn_wire/WireCmd_autogen.h"
#include "dawn_wire/client/ApiObjects_autogen.h"
#include "dawn_wire/client/Client.h" #include "dawn_wire/client/Client.h"
#include "dawn_wire/client/ObjectAllocator.h"
namespace dawn_wire { namespace client { namespace dawn_wire { namespace client {
Device::Device(Client* client, uint32_t initialRefcount, uint32_t initialId) Device::Device(Client* client, uint32_t initialRefcount, uint32_t initialId)
: ObjectBase(this, initialRefcount, initialId), mClient(client) { : ObjectBase(this, initialRefcount, initialId), mClient(client) {
this->device = this; this->device = this;
// Get the default queue for this device.
ObjectAllocator<Queue>::ObjectAndSerial* allocation = mClient->QueueAllocator().New(this);
mDefaultQueue = allocation->object.get();
DeviceGetDefaultQueueCmd cmd;
cmd.self = reinterpret_cast<WGPUDevice>(this);
cmd.result = ObjectHandle{allocation->object->id, allocation->generation};
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(mClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer, *mClient);
} }
Device::~Device() { Device::~Device() {
// Fire pending error scopes
auto errorScopes = std::move(mErrorScopes); auto errorScopes = std::move(mErrorScopes);
for (const auto& it : errorScopes) { for (const auto& it : errorScopes) {
it.second.callback(WGPUErrorType_Unknown, "Device destroyed", it.second.userdata); it.second.callback(WGPUErrorType_Unknown, "Device destroyed", it.second.userdata);
} }
// Destroy the default queue
DestroyObjectCmd cmd;
cmd.objectType = ObjectType::Queue;
cmd.objectId = mDefaultQueue->id;
size_t requiredSize = cmd.GetRequiredSize();
char* allocatedBuffer = static_cast<char*>(mClient->GetCmdSpace(requiredSize));
cmd.Serialize(allocatedBuffer);
mClient->QueueAllocator().Free(mDefaultQueue);
} }
Client* Device::GetClient() { Client* Device::GetClient() {
@ -119,4 +145,9 @@ namespace dawn_wire { namespace client {
return true; return true;
} }
WGPUQueue Device::GetDefaultQueue() {
mDefaultQueue->refcount++;
return reinterpret_cast<WGPUQueue>(mDefaultQueue);
}
}} // namespace dawn_wire::client }} // namespace dawn_wire::client

View File

@ -24,6 +24,7 @@
namespace dawn_wire { namespace client { namespace dawn_wire { namespace client {
class Client; class Client;
struct Queue;
class Device : public ObjectBase { class Device : public ObjectBase {
public: public:
@ -40,6 +41,8 @@ namespace dawn_wire { namespace client {
bool RequestPopErrorScope(WGPUErrorCallback callback, void* userdata); bool RequestPopErrorScope(WGPUErrorCallback callback, void* userdata);
bool PopErrorScope(uint64_t requestSerial, WGPUErrorType type, const char* message); bool PopErrorScope(uint64_t requestSerial, WGPUErrorType type, const char* message);
WGPUQueue GetDefaultQueue();
private: private:
struct ErrorScopeData { struct ErrorScopeData {
WGPUErrorCallback callback = nullptr; WGPUErrorCallback callback = nullptr;
@ -53,8 +56,10 @@ namespace dawn_wire { namespace client {
WGPUErrorCallback mErrorCallback = nullptr; WGPUErrorCallback mErrorCallback = nullptr;
WGPUDeviceLostCallback mDeviceLostCallback = nullptr; WGPUDeviceLostCallback mDeviceLostCallback = nullptr;
bool mDidRunLostCallback = false; bool mDidRunLostCallback = false;
void* mErrorUserdata; void* mErrorUserdata = nullptr;
void* mDeviceLostUserdata; void* mDeviceLostUserdata = nullptr;
Queue* mDefaultQueue = nullptr;
}; };
}} // namespace dawn_wire::client }} // namespace dawn_wire::client

View File

@ -25,7 +25,7 @@ class QueueTests : public DawnTest {};
TEST_P(QueueTests, GetDefaultQueueSameObject) { TEST_P(QueueTests, GetDefaultQueueSameObject) {
wgpu::Queue q1 = device.GetDefaultQueue(); wgpu::Queue q1 = device.GetDefaultQueue();
wgpu::Queue q2 = device.GetDefaultQueue(); wgpu::Queue q2 = device.GetDefaultQueue();
EXPECT_EQ(q1.Get() == q2.Get(), !UsesWire()); EXPECT_EQ(q1.Get(), q2.Get());
} }
DAWN_INSTANTIATE_TEST(QueueTests, DAWN_INSTANTIATE_TEST(QueueTests,

View File

@ -232,11 +232,6 @@ TEST_F(WireArgumentTests, ObjectsAsPointerArgument) {
.WillOnce(Return(apiCmdBufs[i])); .WillOnce(Return(apiCmdBufs[i]));
} }
// Create queue
WGPUQueue queue = wgpuDeviceGetDefaultQueue(device);
WGPUQueue apiQueue = api.GetNewQueue();
EXPECT_CALL(api, DeviceGetDefaultQueue(apiDevice)).WillOnce(Return(apiQueue));
// Submit command buffer and check we got a call with both API-side command buffers // Submit command buffer and check we got a call with both API-side command buffers
wgpuQueueSubmit(queue, 2, cmdBufs); wgpuQueueSubmit(queue, 2, cmdBufs);

View File

@ -43,12 +43,6 @@ class WireFenceTests : public WireTest {
mockFenceOnCompletionCallback = mockFenceOnCompletionCallback =
std::make_unique<StrictMock<MockFenceOnCompletionCallback>>(); std::make_unique<StrictMock<MockFenceOnCompletionCallback>>();
{
queue = wgpuDeviceGetDefaultQueue(device);
apiQueue = api.GetNewQueue();
EXPECT_CALL(api, DeviceGetDefaultQueue(apiDevice)).WillOnce(Return(apiQueue));
FlushClient();
}
{ {
WGPUFenceDescriptor descriptor = {}; WGPUFenceDescriptor descriptor = {};
descriptor.initialValue = 1; descriptor.initialValue = 1;
@ -89,9 +83,6 @@ class WireFenceTests : public WireTest {
// A successfully created fence // A successfully created fence
WGPUFence fence; WGPUFence fence;
WGPUFence apiFence; WGPUFence apiFence;
WGPUQueue queue;
WGPUQueue apiQueue;
}; };
// Check that signaling a fence succeeds // Check that signaling a fence succeeds
@ -227,7 +218,8 @@ TEST_F(WireFenceTests, DestroyBeforeOnCompletionEnd) {
} }
// Test that signaling a fence on a wrong queue is invalid // Test that signaling a fence on a wrong queue is invalid
TEST_F(WireFenceTests, SignalWrongQueue) { // DISABLED until we have support for multiple queues.
TEST_F(WireFenceTests, DISABLED_SignalWrongQueue) {
WGPUQueue queue2 = wgpuDeviceGetDefaultQueue(device); WGPUQueue queue2 = wgpuDeviceGetDefaultQueue(device);
WGPUQueue apiQueue2 = api.GetNewQueue(); WGPUQueue apiQueue2 = api.GetNewQueue();
EXPECT_CALL(api, DeviceGetDefaultQueue(apiDevice)).WillOnce(Return(apiQueue2)); EXPECT_CALL(api, DeviceGetDefaultQueue(apiDevice)).WillOnce(Return(apiQueue2));
@ -240,7 +232,8 @@ TEST_F(WireFenceTests, SignalWrongQueue) {
} }
// Test that signaling a fence on a wrong queue does not update fence signaled value // Test that signaling a fence on a wrong queue does not update fence signaled value
TEST_F(WireFenceTests, SignalWrongQueueDoesNotUpdateValue) { // DISABLED until we have support for multiple queues.
TEST_F(WireFenceTests, DISABLED_SignalWrongQueueDoesNotUpdateValue) {
WGPUQueue queue2 = wgpuDeviceGetDefaultQueue(device); WGPUQueue queue2 = wgpuDeviceGetDefaultQueue(device);
WGPUQueue apiQueue2 = api.GetNewQueue(); WGPUQueue apiQueue2 = api.GetNewQueue();
EXPECT_CALL(api, DeviceGetDefaultQueue(apiDevice)).WillOnce(Return(apiQueue2)); EXPECT_CALL(api, DeviceGetDefaultQueue(apiDevice)).WillOnce(Return(apiQueue2));

View File

@ -69,6 +69,12 @@ class WireMultipleDeviceTests : public testing::Test {
mS2cBuf->SetHandler(mWireClient.get()); mS2cBuf->SetHandler(mWireClient.get());
mClientDevice = mWireClient->GetDevice(); mClientDevice = mWireClient->GetDevice();
// The GetDefaultQueue is done on WireClient startup so we expect it now.
mClientQueue = wgpuDeviceGetDefaultQueue(mClientDevice);
mServerQueue = mApi.GetNewQueue();
EXPECT_CALL(mApi, DeviceGetDefaultQueue(mServerDevice)).WillOnce(Return(mServerQueue));
FlushClient();
} }
~WireHolder() { ~WireHolder() {
@ -97,6 +103,14 @@ class WireMultipleDeviceTests : public testing::Test {
return mServerDevice; return mServerDevice;
} }
WGPUQueue ClientQueue() {
return mClientQueue;
}
WGPUQueue ServerQueue() {
return mServerQueue;
}
private: private:
testing::StrictMock<MockProcTable> mApi; testing::StrictMock<MockProcTable> mApi;
std::unique_ptr<dawn_wire::WireServer> mWireServer; std::unique_ptr<dawn_wire::WireServer> mWireServer;
@ -105,6 +119,8 @@ class WireMultipleDeviceTests : public testing::Test {
std::unique_ptr<utils::TerribleCommandBuffer> mC2sBuf; std::unique_ptr<utils::TerribleCommandBuffer> mC2sBuf;
WGPUDevice mServerDevice; WGPUDevice mServerDevice;
WGPUDevice mClientDevice; WGPUDevice mClientDevice;
WGPUQueue mServerQueue;
WGPUQueue mClientQueue;
}; };
void ExpectInjectedError(WireHolder* wire) { void ExpectInjectedError(WireHolder* wire) {
@ -134,20 +150,12 @@ TEST_F(WireMultipleDeviceTests, ValidatesSameDevice) {
WireHolder wireA; WireHolder wireA;
WireHolder wireB; WireHolder wireB;
// Create the objects // Create the fence
WGPUQueue queueA = wgpuDeviceGetDefaultQueue(wireA.ClientDevice());
WGPUQueue queueB = wgpuDeviceGetDefaultQueue(wireB.ClientDevice());
WGPUFenceDescriptor desc = {}; WGPUFenceDescriptor desc = {};
WGPUFence fenceA = wgpuQueueCreateFence(queueA, &desc); WGPUFence fenceA = wgpuQueueCreateFence(wireA.ClientQueue(), &desc);
// Flush on wire B. We should see the queue created.
EXPECT_CALL(*wireB.Api(), DeviceGetDefaultQueue(wireB.ServerDevice()))
.WillOnce(Return(wireB.Api()->GetNewQueue()));
wireB.FlushClient();
// Signal with a fence from a different wire. // Signal with a fence from a different wire.
wgpuQueueSignal(queueB, fenceA, 1u); wgpuQueueSignal(wireB.ClientQueue(), fenceA, 1u);
// We should inject an error into the server. // We should inject an error into the server.
ExpectInjectedError(&wireB); ExpectInjectedError(&wireB);

View File

@ -70,6 +70,12 @@ void WireTest::SetUp() {
dawnProcSetProcs(&clientProcs); dawnProcSetProcs(&clientProcs);
apiDevice = mockDevice; apiDevice = mockDevice;
// The GetDefaultQueue is done on WireClient startup so we expect it now.
queue = wgpuDeviceGetDefaultQueue(device);
apiQueue = api.GetNewQueue();
EXPECT_CALL(api, DeviceGetDefaultQueue(apiDevice)).WillOnce(Return(apiQueue));
FlushClient();
} }
void WireTest::TearDown() { void WireTest::TearDown() {
@ -104,6 +110,7 @@ dawn_wire::WireClient* WireTest::GetWireClient() {
} }
void WireTest::DeleteServer() { void WireTest::DeleteServer() {
EXPECT_CALL(api, QueueRelease(apiQueue)).Times(1);
mWireServer = nullptr; mWireServer = nullptr;
} }

View File

@ -123,7 +123,9 @@ class WireTest : public testing::Test {
testing::StrictMock<MockProcTable> api; testing::StrictMock<MockProcTable> api;
WGPUDevice apiDevice; WGPUDevice apiDevice;
WGPUQueue apiQueue;
WGPUDevice device; WGPUDevice device;
WGPUQueue queue;
dawn_wire::WireServer* GetWireServer(); dawn_wire::WireServer* GetWireServer();
dawn_wire::WireClient* GetWireClient(); dawn_wire::WireClient* GetWireClient();