| // Copyright 2021 The Dawn Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "dawn_wire/server/Server.h" |
| |
| #include "dawn_wire/SupportedFeatures.h" |
| |
| #include <algorithm> |
| |
| namespace dawn::wire::server { |
| |
| bool Server::DoInstanceRequestAdapter(ObjectId instanceId, |
| uint64_t requestSerial, |
| ObjectHandle adapterHandle, |
| const WGPURequestAdapterOptions* options) { |
| auto* instance = InstanceObjects().Get(instanceId); |
| if (instance == nullptr) { |
| return false; |
| } |
| |
| auto* resultData = AdapterObjects().Allocate(adapterHandle.id, AllocationState::Reserved); |
| if (resultData == nullptr) { |
| return false; |
| } |
| |
| resultData->generation = adapterHandle.generation; |
| |
| auto userdata = MakeUserdata<RequestAdapterUserdata>(); |
| userdata->instance = ObjectHandle{instanceId, instance->generation}; |
| userdata->requestSerial = requestSerial; |
| userdata->adapterObjectId = adapterHandle.id; |
| |
| mProcs.instanceRequestAdapter(instance->handle, options, |
| ForwardToServer<&Server::OnRequestAdapterCallback>, |
| userdata.release()); |
| return true; |
| } |
| |
| void Server::OnRequestAdapterCallback(RequestAdapterUserdata* data, |
| WGPURequestAdapterStatus status, |
| WGPUAdapter adapter, |
| const char* message) { |
| auto* adapterObject = |
| AdapterObjects().Get(data->adapterObjectId, AllocationState::Reserved); |
| // Should be impossible to fail. ObjectIds can't be freed by a destroy command until |
| // they move from Reserved to Allocated, or if they are destroyed here. |
| ASSERT(adapterObject != nullptr); |
| |
| ReturnInstanceRequestAdapterCallbackCmd cmd = {}; |
| cmd.instance = data->instance; |
| cmd.requestSerial = data->requestSerial; |
| cmd.status = status; |
| cmd.message = message; |
| |
| if (status != WGPURequestAdapterStatus_Success) { |
| // Free the ObjectId which will make it unusable. |
| AdapterObjects().Free(data->adapterObjectId); |
| ASSERT(adapter == nullptr); |
| SerializeCommand(cmd); |
| return; |
| } |
| |
| WGPUAdapterProperties properties = {}; |
| WGPUSupportedLimits limits = {}; |
| std::vector<WGPUFeatureName> features; |
| |
| // Assign the handle and allocated status if the adapter is created successfully. |
| adapterObject->state = AllocationState::Allocated; |
| adapterObject->handle = adapter; |
| |
| size_t featuresCount = mProcs.adapterEnumerateFeatures(adapter, nullptr); |
| features.resize(featuresCount); |
| mProcs.adapterEnumerateFeatures(adapter, features.data()); |
| |
| // Hide features the wire cannot support. |
| auto it = std::partition(features.begin(), features.end(), IsFeatureSupported); |
| |
| cmd.featuresCount = std::distance(features.begin(), it); |
| cmd.features = features.data(); |
| |
| mProcs.adapterGetProperties(adapter, &properties); |
| mProcs.adapterGetLimits(adapter, &limits); |
| cmd.properties = &properties; |
| cmd.limits = &limits; |
| |
| SerializeCommand(cmd); |
| } |
| |
| } // namespace dawn::wire::server |