// Copyright 2018 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.

/// Magma is the driver model for GPUs/NPUs on Fuchsia.
///
/// Magma has two driver components: a hardware-specific library loaded into each application’s
/// address space ("client driver", sometimes known as "Installable client driver" or "ICD");
/// and the Magma system driver that interfaces with the hardware.
/// The communication protocols between the two driver pieces are defined here.
///
/// Some names have a numeric suffix (eg, BufferRangeOp2); the number is a detail of how the
/// protocols have evolved, and can be ignored.
@available(added=9)
library fuchsia.gpu.magma;

using fuchsia.url;
using zx;
using fuchsia.memorypressure;

/// Types of information about the hardware and driver that can be queried from the Magma system
/// driver. Vendor-specific ID numbers may be used, but those IDs will be listed elsewhere.
type QueryId = flexible enum : uint64 {
    /// Returns the hardware vendor ID (simple result) - should be the PCI ID of the hardware
    /// vendor if possible, or the Khronos vendor ID otherwise.
    VENDOR_ID = 0;

    /// Returns the hardware device ID (simple result)
    DEVICE_ID = 1;

    /// Returns the version of the vendor interfaces supported by the system driver.
    @available(added=12)
    VENDOR_VERSION = 2;

    /// Returns true if MAGMA_QUERY_TOTAL_TIME is supported (simple result)
    IS_TOTAL_TIME_SUPPORTED = 3;

    /// Upper 32bits: max inflight messages, lower 32bits: max inflight memory (MB) (simple result)
    MAXIMUM_INFLIGHT_PARAMS = 5;

    /// Returns a struct magma_total_time_query_result (buffer result); see:
    /// src/graphics/lib/magma/include/magma/magma_common_defs.h
    MAGMA_QUERY_TOTAL_TIME = 500;

    /// Vendor specific query IDs start here
    VENDOR_QUERY_0 = 10000;
};

/// The maximum number of ICDs supported by a Magma system driver.
const MAX_ICD_COUNT uint64 = 8;

type IcdFlags = flexible bits : uint32 {
    SUPPORTS_VULKAN = 1;
    SUPPORTS_OPENCL = 2;
    // Exposes the fuchsia.mediacodec.CodecFactory FIDL interface.
    SUPPORTS_MEDIA_CODEC_FACTORY = 4;
};

/// Information about an ICD implementation that can be used with a Magma device.
type IcdInfo = table {
    /// URL of the component implementation that provides the ICD.
    1: component_url fuchsia.url.Url;

    /// Flags describing the basic capabilities of the ICD, including what APIs it supports.
    2: flags IcdFlags;
};

/// The Magma Device protocol allow clients to learn about the hardware by making queries, such as
/// device and vendor IDs, and which client drivers are supported by the device's system driver.  
/// To engage further with the device, clients may establish connections formed of channel pairs:
/// a primary channel for making requests (see Primary protocol below), and a secondary channel
/// for receiving notification messages (see Notification protocol below).
closed protocol Device {
    /// On success, returns a result either in a buffer or a simple value.
    strict Query(struct {
        query_id QueryId;
    }) -> (strict resource union {
        1: simple_result uint64;
        2: buffer_result zx.Handle:VMO;
    }) error zx.Status;

    /// Creates a connection to the device comprised of two IPC channels.
    /// The primary channel is for the Primary protocol (see below).  The notification channel is
    /// used for vendor-specific messages which are sent only in the reverse (server-client)
    /// direction, typically in response to client command completion.
    strict Connect2(resource struct {
        client_id uint64;
        primary_channel server_end:Primary;
        notification_channel server_end:Notification;
    });
};

/// Methods used to expose diagnostics from the Magma device.
closed protocol DiagnosticDevice {
    /// Dumps driver and hardware state to the log.
    strict DumpState(struct {
        dump_type uint32;
    });
};

/// Methods implemented by an MSD and exposed for use of an ICD loader.
closed protocol IcdLoaderDevice {
    /// Returns a list of ICDs that can be used with this Magma device. The list is sorted in
    /// descending order of preference.
    strict GetIcdList() -> (struct {
        icd_list vector<IcdInfo>:MAX_ICD_COUNT;
    });
};

/// A combination of all the production |Device| protocols. This protocol is implemented on the
/// Magma service side and should not be used by clients.
closed protocol CombinedDevice {
    compose Device;
    compose DiagnosticDevice;
    compose IcdLoaderDevice;
};

/// Additional device methods for the purposes of testing the MSD and should not be used by ICDs.
closed protocol TestDevice {
    compose CombinedDevice;

    strict GetUnitTestStatus() -> (struct {
        status zx.Status;
    });
};

@available(added=13)
type Object = flexible resource union {
    1: semaphore zx.Handle:EVENT;
    2: buffer zx.Handle:VMO;
    3: vmo_semaphore zx.Handle:VMO;
};

type ObjectType = flexible enum : uint32 {
    @available(deprecated=17, removed=18)
    EVENT = 10;
    /// A memory object backeed by a Zircon VMO.
    BUFFER = 11;
    /// A sync object backed by a Zircon event or VMO.
    @available(added=13)
    SEMAPHORE = 12;
};

alias ObjectId = uint64;

@available(added=13)
type ImportFlags = flexible bits : uint64 {
    SEMAPHORE_ONE_SHOT = 0x1;
};

type BufferOp = flexible enum : uint32 {
    /// Populate the hardware page tables with the pages mapped in this range, committing pages
    /// as needed. This is not needed for allocations mapped GROWABLE, since the page tables will
    /// be populated on demand.
    POPULATE_TABLES = 1;

    /// Depopulate page table mappings for this range. This prevents the hardware from accessing
    /// pages in that range, but the pages retain their contents.
    DEPOPULATE_TABLES = 2;
};

/// The batch size used to send multiple immediate commands in a single message.
const MAX_IMMEDIATE_COMMANDS_DATA_SIZE uint32 = 2048;

/// The batch size used to send multiple inline commands in a single message.
@available(added=15)
const MAX_INLINE_COMMANDS_DATA_SIZE uint32 = 2048;

type MapFlags = flexible bits : uint64 {
    READ = 0x1;
    WRITE = 0x2;
    EXECUTE = 0x4;
    /// Uncommitted pages may be comitted on a hardware fault. If this flag is not set, access
    /// faults should cause an error.
    GROWABLE = 0x8;

    /// Vendor specific definitions start here
    VENDOR_FLAG_0 = 0x10000;
};

type CommandBufferFlags = flexible bits : uint64 {
    /// Vendor specific definitions start here
    VENDOR_FLAG_0 = 0x10000;
};

/// A command buffer may be used to pass hardware instructions in a shared buffer (VMO).
type CommandBuffer = struct {
    /// Index of the resource containing instructions to start the command buffer.
    resource_index uint32;

    /// Starting offset within the resource.
    start_offset uint64;
};

@available(added=15)
type InlineCommand = table {
    1: data vector<uint8>:MAX;
    2: semaphores vector<ObjectId>:MAX;
};

/// Performance counter pools contain byte ranges of buffers. Whenever a performance counter dump is
/// triggered, the driver removes a range from the pool, writes the performance counter values from
/// the hardware into it, then signals the client using OnPerformanceCounterReadCompleted. Pool IDs
/// are arbitrary uint64 values that are allocated by the client.
alias PerformanceCounterPoolId = uint64;

type ResultFlags = flexible bits {
    /// This bit is set in result_flags if the performance counters missed some samples, e.g. due to
    /// the hardware being in protected mode for part of the time.
    DISCONTINUITY = 1;
};

type BufferRange = struct {
    buffer_id ObjectId;
    offset uint64;
    size uint64;
};

alias ContextId = uint32;

alias PerformanceCounterTriggerId = uint32;

/// Describes a set of performance counters. The exact meaning depends on the specific driver, but
/// often is a bitvector representing whether each performance counter is enabled or disabled.
alias PerformanceCounterSet = vector<uint64>:64;

/// If a system driver error occurs, or if the client sends a message that the client should have
/// known is invalid, the connection will be closed and a zx.Status sent via epitaph.
closed protocol Primary {
    @available(deprecated=17, removed=18)
    strict ImportObject2(resource struct {
        object zx.Handle;
        object_type ObjectType;
        object_id ObjectId;
    });

    /// Imports an object for use in the system driver.
    @available(added=13)
    strict ImportObject(resource table {
        /// Required.
        1: object Object;

        /// Required.
        2: object_type ObjectType;

        /// Required.
        3: object_id ObjectId;

        /// Optional
        4: flags ImportFlags;
    });

    /// Destroys the object with `object_id` within this connection.
    strict ReleaseObject(struct {
        object_id ObjectId;
        object_type ObjectType;
    });

    /// Creates context `context_id` for use in command execution.  A context may be associated
    /// with hardware state.
    strict CreateContext(struct {
        context_id ContextId;
    });

    /// Destroys context `context_id`.
    strict DestroyContext(struct {
        context_id ContextId;
    });

    /// Submits command buffers for execution on the hardware, with associated `resources`.
    /// `resources` must refer to buffers that have been imported.
    /// `wait_semaphores` and `signal_semaphores` must refer to events that have been imported.
    /// `wait_semaphores` must all be signaled before execution begins, then are reset.
    /// `signal_semaphores` will be signaled after the command buffer is completed.
    strict ExecuteCommand(struct {
        context_id ContextId;
        resources vector<BufferRange>:MAX;
        command_buffers vector<CommandBuffer>:MAX;
        wait_semaphores vector<ObjectId>:MAX;
        signal_semaphores vector<ObjectId>:MAX;
        flags CommandBufferFlags;
    });

    /// Submits a series of commands for execution on the hardware without using a command buffer.
    /// `semaphores` must refer to events that have been imported, and will be signaled after
    /// the commands are completed.
    strict ExecuteImmediateCommands(struct {
        context_id ContextId;
        command_data vector<uint8>:MAX_IMMEDIATE_COMMANDS_DATA_SIZE;
        semaphores vector<ObjectId>:MAX;
    });

    /// Submits a series of commands for execution on the hardware without using a command buffer.
    /// The number of commands sent should be calculated so that the total message size is less than
    /// MAX_INLINE_COMMANDS_DATA_SIZE.
    @available(added=15)
    strict ExecuteInlineCommands(struct {
        context_id ContextId;
        commands vector<InlineCommand>:MAX;
    });

    /// Incurs a round-trip to the system driver, used to ensure all previous messages have been
    /// observed, but not necessarily completed.
    strict Flush() -> ();

    /// Maps a page range onto the hardware in the connection's address space at address `hw_va`.
    /// `flags` is a set of flags from MapFlags that specify how the hardware can access the buffer.
    strict MapBuffer(table {
        /// Required.
        1: hw_va uint64;

        /// Required.
        2: range BufferRange;

        3: flags MapFlags;
    });

    /// Releases the mapping at address `hw_va` from the hardware for the given `buffer_id`.
    /// Buffers will also be implicitly unmapped when released.
    strict UnmapBuffer(table {
        /// Required.
        1: hw_va uint64;

        /// Required.
        2: buffer_id ObjectId;
    });

    /// Perform an operation on a range of the buffer.
    strict BufferRangeOp2(struct {
        op BufferOp;
        range BufferRange;
    });

    /// Enables the events OnNotifyMessagesConsumed and OnNotifyMemoryImported.
    strict EnableFlowControl();

    /// Indicates the given number of messages were consumed by the server.
    /// The caller should limit the number of inflight messages:
    /// (messages sent - server consumed) <= MaxMessages (see QueryId::MAXIMUM_INFLIGHT_PARAMS).
    /// Messages are actually consumed by the server as quickly as possible, however this event
    /// is sent by the server only when the consumed count reaches half the maximum.
    strict -> OnNotifyMessagesConsumed(struct {
        count uint64;
    });

    /// Indicates the given number of buffer memory bytes were imported by the server.
    /// The caller should limit the amount of memory from inflight ImportBuffer messages:
    /// (bytes sent - server imported) <= MaxBytes (see QueryId::MAXIMUM_INFLIGHT_PARAMS).
    /// This is a soft limit designed to prevent excessive memory consumption, but for large
    /// messages the client may exceed the limit.
    /// Memory is imported by the server as quickly as possible, however this event
    /// is sent only when the consumed byte count reaches half the maximum; therefore,
    /// if the client's count of inflight bytes is less than max/2, the client should send the
    /// ImportBuffer message regardless of its size.
    strict -> OnNotifyMemoryImported(struct {
        bytes uint64;
    });

    /// Tries to enable performance counter FIDL messages. To be successful, |access_token| must
    /// have been returned by PerformanceCounterAccess.GetPerformanceCountToken() from the matching
    /// device.
    strict EnablePerformanceCounterAccess(resource struct {
        access_token zx.Handle:EVENT;
    });

    /// Returns true if any EnablePerformanceCounterAccess message has succeeded.
    strict IsPerformanceCounterAccessAllowed() -> (struct {
        enabled bool;
    });

    /// Enables a set of performance counters.  Disables enabled performance counters that are not
    /// in the new set. Performance counters will also be automatically disabled on connection
    /// close. Performance counter access must have been enabled using
    /// EnablePerformanceCounterAccess before calling this method.
    strict EnablePerformanceCounters(struct {
        counters PerformanceCounterSet;
    });

    /// Creates a pool of buffers that performance counters can be dumped into. Performance counter
    /// access must have been enabled using EnablePerformanceCounterAccess before calling this
    /// method.
    strict CreatePerformanceCounterBufferPool(resource struct {
        pool_id PerformanceCounterPoolId;
        event_channel server_end:PerformanceCounterEvents;
    });

    /// Releases a pool of performance counter buffers. Performance counter access must have been
    /// enabled using EnablePerformanceCounterAccess before calling this method.
    strict ReleasePerformanceCounterBufferPool(struct {
        pool_id PerformanceCounterPoolId;
    });

    /// Adds a set of offsets into buffers to the pool. |offsets[n].buffer_id| is the id of a
    /// buffer that was previously imported using ImportBuffer(). The same buffer may be added to
    /// multiple pools. The pool will hold on to a reference to the buffer even after ReleaseBuffer
    /// is called.  When dumped into this entry, counters will be written starting at
    /// |offsets[n].buffer_offset| bytes into the buffer, and up to |offsets[n].buffer_offset| +
    /// |offsets[n].buffer_size|. |offsets[n].buffer_size| must be large enough to fit all enabled
    /// counters. Performance counter access must have been enabled using
    /// EnablePerformanceCounterAccess before calling this method.
    strict AddPerformanceCounterBufferOffsetsToPool(struct {
        pool_id PerformanceCounterPoolId;
        offsets vector<BufferRange>:64;
    });

    /// Removes every offset of a buffer from the pool. Once this method is finished being handled
    /// on the server, no more dumps will be processed into this buffer. In-flight dumps into this
    /// buffer may be lost.  Performance counter access must have been enabled using
    /// EnablePerformanceCounterAccess before calling this method.
    strict RemovePerformanceCounterBufferFromPool(struct {
        pool_id PerformanceCounterPoolId;
        buffer_id ObjectId;
    });

    /// Triggers dumping of the performance counters into a buffer pool. May fail silently if there
    /// are no buffers in the pool. |trigger_id| is an arbitrary ID assigned by the client that can
    /// be returned in OnPerformanceCounterReadCompleted. Performance counter access must have been
    /// enabled using EnablePerformanceCounterAccess before calling this method.
    strict DumpPerformanceCounters(struct {
        pool_id PerformanceCounterPoolId;
        trigger_id PerformanceCounterTriggerId;
    });

    /// Sets the values of all listed performance counters to 0. May not be supported by some
    /// hardware. Performance counter access must have been enabled using
    /// EnablePerformanceCounterAccess before calling this method.
    strict ClearPerformanceCounters(struct {
        counters PerformanceCounterSet;
    });
};

/// This protocol is empty as the message contents are vendor specific.
closed protocol Notification {};

/// This protocol is implemented by ZX_PROTOCOL_GPU_PERFORMANCE_COUNTERS devices.
closed protocol PerformanceCounterAccess {
    /// This access token is not used as an event, but is instead passed to
    /// Primary.EnablePerformanceCounterAccess.
    strict GetPerformanceCountToken() -> (resource struct {
        access_token zx.Handle:EVENT;
    });
};

closed protocol PerformanceCounterEvents {
    /// Signals that a performance counter buffer has data. These will be output in the order of
    /// when the reads are completed.
    strict -> OnPerformanceCounterReadCompleted(table {
        /// Required.
        1: trigger_id PerformanceCounterTriggerId;

        /// Required.
        2: buffer_id ObjectId;

        /// Required.
        3: buffer_offset uint32;

        /// Required.
        4: timestamp zx.Time;

        /// Required.
        5: flags ResultFlags;
    });
};

/// This protocol is implemented by ZX_PROTOCOL_GPU_DEPENDENCY_INJECTION devices. It's used
/// to inject dependencies on other services into the MSD. It can be used
/// only by a privileged process.
closed protocol DependencyInjection {
    /// Provides a `fuchsia.memorypressure.Provider` implementation to the MSD.
    strict SetMemoryPressureProvider(resource struct {
        provider client_end:fuchsia.memorypressure.Provider;
    });
};
