blob: d13cd847074e23b1257e76313075ce4679b4b5a4 [file] [log] [blame]
// Copyright 2023 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.
#ifndef SRC_GRAPHICS_MAGMA_INCLUDE_LIB_MAGMA_SERVICE_MSD_H_
#define SRC_GRAPHICS_MAGMA_INCLUDE_LIB_MAGMA_SERVICE_MSD_H_
#include <lib/async/dispatcher.h>
#include <lib/inspect/cpp/inspector.h>
#include <lib/magma_service/msd_defs.h> // IWYU pragma: export
#include <lib/stdcompat/span.h>
#include <lib/zx/event.h>
#include <lib/zx/vmo.h>
#include <memory>
namespace msd {
class Connection;
class Device;
class Semaphore;
class Buffer;
class Context;
// This struct represents all the information about the device that the driver needs to interact
// with it. The implementation of this struct is driver-specific.
struct DeviceHandle;
// This represents the driver for a device. It's a singleton that can't access device registers.
class Driver {
public:
static std::unique_ptr<Driver> Create();
virtual ~Driver() = 0;
// Configures the driver according to |flags|.
virtual void Configure(uint32_t flags) {}
// Returns a buffer handle that contains inspect data for the driver. Returns
// ZX_HANDLE_INVALID if driver doesn't support inspect.
virtual std::optional<inspect::Inspector> DuplicateInspector() { return std::nullopt; }
// Creates a device at system startup. `device_data` is a pointer to a platform-specific device
// object which is guaranteed to outlive the returned Device.
virtual std::unique_ptr<Device> CreateDevice(DeviceHandle* device_data) { return {}; }
// Creates a buffer that owns the provided handle. Can be called on any thread.
virtual std::unique_ptr<Buffer> ImportBuffer(zx::vmo vmo, uint64_t client_id) { return {}; }
// Creates a semaphore that owns the provided handle. Can be called on any thread.
virtual magma_status_t ImportSemaphore(zx::handle handle, uint64_t client_id, uint64_t flags,
std::unique_ptr<Semaphore>* out) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
};
// This represents a single hardware device. Unless otherwise specified, all calls into this class
// are serialized.
class Device {
public:
virtual ~Device() = 0;
// Signals the current memory pressure level for the system. May be called on any thread.
virtual void SetMemoryPressureLevel(MagmaMemoryPressureLevel level) {}
// Returns a value associated with the given id. On MAGMA_STATUS_OK, a given query `id` will
// return either a buffer in `result_buffer_out`, or a value in `result_out`. nullptr may be
// provided for whichever result parameter is not needed.
virtual magma_status_t Query(uint64_t id, zx::vmo* result_buffer_out, uint64_t* result_out) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
// Outputs a list of ICD components.
virtual magma_status_t GetIcdList(std::vector<MsdIcdInfo>* icd_info_out) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual void DumpStatus(uint32_t dump_flags) {}
// Opens a device for the given client. Returns nullptr on failure
virtual std::unique_ptr<Connection> Open(msd_client_id_t client_id) { return {}; }
};
struct PerfCounterResult {
uint64_t pool_id;
uint32_t trigger_id;
uint64_t buffer_id;
uint32_t buffer_offset;
uint64_t timestamp;
uint32_t result_flags;
};
// Implemented by sys_driver. This class is used to call into sys_driver to notify it of operations
// it needs to handle.
class NotificationHandler {
public:
virtual void NotificationChannelSend(cpp20::span<uint8_t> data) = 0;
virtual void ContextKilled() = 0;
virtual void PerformanceCounterReadCompleted(const PerfCounterResult& result) = 0;
// Returns an async_dispatcher_t that runs commands serialized with this
// Connection. This dispatcher will be shut down before the Connection is
// destroyed.
virtual async_dispatcher_t* GetAsyncDispatcher() = 0;
};
class PerfCountPool {
public:
virtual ~PerfCountPool() = 0;
};
// This represents a single connection from a client. All method calls on this class are serialized.
class Connection {
public:
virtual ~Connection() = 0;
virtual magma_status_t MapBuffer(Buffer& buffer, uint64_t gpu_va, uint64_t offset,
uint64_t length, uint64_t flags) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t UnmapBuffer(Buffer& buffer, uint64_t gpu_va) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t BufferRangeOp(Buffer& buffer, uint32_t options, uint64_t start_offset,
uint64_t length) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
// Signals that the given |buffer| is no longer in use on the given |connection|. This must be
// called for every connection associated with a buffer before the buffer is destroyed, or for
// every buffer associated with a connection before the connection is destroyed.
virtual void ReleaseBuffer(Buffer& buffer) {}
// Sets the callback to be used by a connection for various notifications.
// This is called when a connection is created, and also called to unset
// the callback before a connection is destroyed. A multithreaded
// implementation must be careful to guard use of this callback to avoid
// collision with possible concurrent destruction.
virtual void SetNotificationCallback(NotificationHandler* handler) {}
virtual std::unique_ptr<Context> CreateContext() { return {}; }
virtual magma_status_t EnablePerformanceCounters(cpp20::span<const uint64_t> counters) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t CreatePerformanceCounterBufferPool(
uint64_t pool_id, std::unique_ptr<PerfCountPool>* pool_out) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
// Releases the performance counter buffer pool. This driver must not send any notification with
// the pool ID of this pool after it returns from this method.
virtual magma_status_t ReleasePerformanceCounterBufferPool(std::unique_ptr<PerfCountPool> pool) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t AddPerformanceCounterBufferOffsetToPool(PerfCountPool& pool,
Buffer& buffer, uint64_t buffer_id,
uint64_t buffer_offset,
uint64_t buffer_size) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t RemovePerformanceCounterBufferFromPool(PerfCountPool& pool,
Buffer& buffer) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t DumpPerformanceCounters(PerfCountPool& pool, uint32_t trigger_id) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t ClearPerformanceCounters(cpp20::span<const uint64_t> counters) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
};
// This represents a single hardware context that may execute commands.
class Context {
public:
virtual ~Context() = 0;
// Executes a command buffer given associated set of resources and semaphores.
// |command_buffer| is the command buffer to be executed
// |exec_resources| describe the associated resources
// |buffers| are the buffers referenced the ids in |exec_resource|, in the same order
// |wait_semaphores| are the semaphores that must be signaled before starting command buffer
// execution
// |signal_semaphores| are the semaphores to be signaled upon completion of the command buffer
virtual magma_status_t ExecuteCommandBufferWithResources(magma_command_buffer* command_buffer,
magma_exec_resource* exec_resources,
Buffer** buffers,
Semaphore** wait_semaphores,
Semaphore** signal_semaphores) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
// Executes a buffer of commands. `semaphores` is a set of semaphores that may be used by the
// commands; the exact usage is driver-dependent.
virtual magma_status_t ExecuteImmediateCommands(cpp20::span<uint8_t> commands,
cpp20::span<Semaphore*> semaphores) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
virtual magma_status_t ExecuteInlineCommand(magma_inline_command_buffer* command,
Semaphore** semaphores) {
return MAGMA_STATUS_UNIMPLEMENTED;
}
};
class Buffer {
public:
virtual ~Buffer() = 0;
};
class Semaphore {
public:
virtual ~Semaphore() = 0;
};
} // namespace msd
#endif // SRC_GRAPHICS_MAGMA_INCLUDE_LIB_MAGMA_SERVICE_MSD_H_