// 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, legacy=true)
    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, legacy=true)
    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;
    });
};
