blob: b00b97ced36cc37c4b1ec09b17f63e095915a17b [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/graphics/bin/vulkan_loader/magma_device.h"
#include <lib/fdio/directory.h>
#include <lib/fdio/io.h>
#include <lib/fdio/unsafe.h>
#include <lib/syslog/cpp/macros.h>
#include "src/graphics/bin/vulkan_loader/app.h"
// static
std::unique_ptr<MagmaDevice> MagmaDevice::Create(LoaderApp* app, int dir_fd, std::string name,
inspect::Node* parent) {
std::unique_ptr<MagmaDevice> device(new MagmaDevice(app));
if (!device->Initialize(dir_fd, name, parent))
return nullptr;
return device;
}
bool MagmaDevice::Initialize(int dir_fd, std::string name, inspect::Node* parent) {
node() = parent->CreateChild("magma-" + name);
fdio_t* dir_fdio = fdio_unsafe_fd_to_io(dir_fd);
if (!dir_fdio) {
FX_LOGS(ERROR) << "Failed to get fdio_t";
return false;
}
zx_handle_t dir_handle;
dir_handle = fdio_unsafe_borrow_channel(dir_fdio);
if (!dir_handle) {
FX_LOGS(ERROR) << "Failed to borrow channel";
return false;
}
zx_status_t status;
status = fdio_service_connect_at(dir_handle, name.c_str(),
device_.NewRequest().TakeChannel().release());
if (status != ZX_OK) {
FX_PLOGS(ERROR, status) << "Failed to connect to service";
return false;
}
fdio_unsafe_release(dir_fdio);
device_.set_error_handler([this](zx_status_t status) {
// Deletes |this|.
app()->RemoveDevice(this);
});
device_->GetIcdList([this, name](std::vector<fuchsia::gpu::magma::IcdInfo> icd_info) mutable {
uint32_t i = 0;
for (auto& icd : icd_info) {
if (!icd.has_component_url()) {
FX_LOGS(ERROR) << "ICD missing component URL";
continue;
}
if (!icd.has_flags()) {
FX_LOGS(ERROR) << "ICD missing flags";
continue;
}
IcdData data;
data.node = node().CreateChild(std::to_string(i++));
data.node.CreateString("component_url", icd.component_url(), &data.values);
data.node.CreateUint("flags", static_cast<uint32_t>(icd.flags()), &data.values);
icds().push_back(std::move(data));
}
});
return true;
}