blob: 7ec99f438c3b531aa7fec38529a85302ebfc0fb0 [file] [log] [blame]
Austin Eng07e76672021-12-15 21:52:17 +00001// Copyright 2021 The Dawn Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "dawn_wire/server/Server.h"
16
17#include "dawn_wire/SupportedFeatures.h"
18
Corentin Wallez7f8fa042022-01-06 09:22:17 +000019namespace dawn_wire::server {
Austin Eng07e76672021-12-15 21:52:17 +000020
21 bool Server::DoAdapterRequestDevice(ObjectId adapterId,
22 uint64_t requestSerial,
23 ObjectHandle deviceHandle,
24 const WGPUDeviceDescriptor* descriptor) {
25 auto* adapter = AdapterObjects().Get(adapterId);
26 if (adapter == nullptr) {
27 return false;
28 }
29
30 auto* resultData = DeviceObjects().Allocate(deviceHandle.id, AllocationState::Reserved);
31 if (resultData == nullptr) {
32 return false;
33 }
34
35 resultData->generation = deviceHandle.generation;
36
37 auto userdata = MakeUserdata<RequestDeviceUserdata>();
38 userdata->adapter = ObjectHandle{adapterId, adapter->generation};
39 userdata->requestSerial = requestSerial;
40 userdata->deviceObjectId = deviceHandle.id;
41
Corentin Wallez31f12242022-01-06 09:09:49 +000042 mProcs.adapterRequestDevice(adapter->handle, descriptor,
43 ForwardToServer<&Server::OnRequestDeviceCallback>,
44 userdata.release());
Austin Eng07e76672021-12-15 21:52:17 +000045 return true;
46 }
47
Corentin Wallez31f12242022-01-06 09:09:49 +000048 void Server::OnRequestDeviceCallback(RequestDeviceUserdata* data,
49 WGPURequestDeviceStatus status,
Austin Eng07e76672021-12-15 21:52:17 +000050 WGPUDevice device,
Corentin Wallez31f12242022-01-06 09:09:49 +000051 const char* message) {
Austin Eng07e76672021-12-15 21:52:17 +000052 auto* deviceObject = DeviceObjects().Get(data->deviceObjectId, AllocationState::Reserved);
53 // Should be impossible to fail. ObjectIds can't be freed by a destroy command until
54 // they move from Reserved to Allocated, or if they are destroyed here.
55 ASSERT(deviceObject != nullptr);
56
57 ReturnAdapterRequestDeviceCallbackCmd cmd = {};
58 cmd.adapter = data->adapter;
59 cmd.requestSerial = data->requestSerial;
60 cmd.status = status;
61 cmd.message = message;
62
63 if (status != WGPURequestDeviceStatus_Success) {
64 // Free the ObjectId which will make it unusable.
65 DeviceObjects().Free(data->deviceObjectId);
66 ASSERT(device == nullptr);
67 SerializeCommand(cmd);
68 return;
69 }
70
71 std::vector<WGPUFeatureName> features;
72
Austin Eng3ac7b9c2022-01-06 22:11:28 +000073 size_t featuresCount = mProcs.deviceEnumerateFeatures(device, nullptr);
Austin Eng07e76672021-12-15 21:52:17 +000074 features.resize(featuresCount);
75 mProcs.deviceEnumerateFeatures(device, features.data());
76
77 // The client should only be able to request supported features, so all enumerated
78 // features that were enabled must also be supported by the wire.
79 // Note: We fail the callback here, instead of immediately upon receiving
80 // the request to preserve callback ordering.
81 for (WGPUFeatureName f : features) {
82 if (!IsFeatureSupported(f)) {
83 // Release the device.
84 mProcs.deviceRelease(device);
85 // Free the ObjectId which will make it unusable.
86 DeviceObjects().Free(data->deviceObjectId);
87
88 cmd.status = WGPURequestDeviceStatus_Error;
89 cmd.message = "Requested feature not supported.";
90 SerializeCommand(cmd);
91 return;
92 }
93 }
94
95 cmd.featuresCount = features.size();
96 cmd.features = features.data();
97
98 WGPUSupportedLimits limits = {};
99 mProcs.deviceGetLimits(device, &limits);
100 cmd.limits = &limits;
101
102 // Assign the handle and allocated status if the device is created successfully.
103 deviceObject->state = AllocationState::Allocated;
104 deviceObject->handle = device;
105 SetForwardingDeviceCallbacks(deviceObject);
106
107 SerializeCommand(cmd);
108 }
109
Corentin Wallez7f8fa042022-01-06 09:22:17 +0000110} // namespace dawn_wire::server