blob: 65b11d5c1e0110211049a4967b97227874067c9c [file] [log] [blame]
// 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.
library fuchsia.gpu.magma;
using fuchsia.url;
using zx;
using fuchsia.memorypressure;
type QueryId = strict enum {
VENDOR_ID = 0;
DEVICE_ID = 1;
IS_TEST_RESTART_SUPPORTED = 2;
IS_TOTAL_TIME_SUPPORTED = 3;
// 4 was MINIMUM_MAPPABLE_ADDRESS
/// Upper 32bits: max inflight messages, lower 32bits: max inflight memory (MB)
MAXIMUM_INFLIGHT_PARAMS = 5;
/// Vendor specific query IDs start here
VENDOR_QUERY_0 = 10000;
};
type Status = strict enum {
INTERNAL_ERROR = 1;
INVALID_ARGS = 2;
ACCESS_DENIED = 3;
MEMORY_ERROR = 4;
CONTEXT_KILLED = 5;
CONNECTION_LOST = 6;
TIMED_OUT = 7;
UNIMPLEMENTED = 8;
/// An object was not in the right state for an operation on it.
BAD_STATE = 9;
};
type ObjectType = strict enum {
SEMAPHORE = 10;
BUFFER = 11;
};
type BufferOp = strict enum {
/// Eagerly populate GPU page tables with the pages mapping in this range, committing pages as
/// needed. This is not needed for MAGMA_GPU_MAP_FLAG_GROWABLE allocations, since the page
/// tables will be populated on demand.
POPULATE_TABLES = 1;
/// Depopulate GPU page table mappings for this range. This prevents the GPU from accessing
/// pages in that range, but the pages retain their contents.
DEPOPULATE_TABLES = 2;
};
const MAX_ICD_COUNT uint64 = 8;
type IcdFlags = flexible bits : uint32 {
SUPPORTS_VULKAN = 1;
};
/// 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;
};
protocol Device {
/// Returns a parameter, or an error.
Query2(struct {
query_id uint64;
}) -> (struct {
result uint64;
}) error Status;
/// Returns a buffer, or an error.
QueryReturnsBuffer(struct {
query_id uint64;
}) -> (resource struct {
buffer zx.handle:VMO;
}) error Status;
/// Get the magma ipc channels.
Connect(struct {
client_id uint64;
}) -> (resource struct {
primary_channel zx.handle:CHANNEL;
notification_channel zx.handle:CHANNEL;
});
/// Dumps driver and hardware state.
DumpState(struct {
dump_type uint32;
});
/// Gets a list of ICDs that can be used with this magma device. The list is sorted in descending
/// order of preference.
GetIcdList() -> (struct {
icd_list vector<IcdInfo>:MAX_ICD_COUNT;
});
/// For testing only.
TestRestart();
/// For testing only - on non-test drivers this will close the channel.
GetUnitTestStatus() -> (struct {
status zx.status;
});
};
/// The batch size used to send multiple immediate commands in a single message.
const MAX_IMMEDIATE_COMMANDS_DATA_SIZE uint32 = 2048;
type MapFlags = flexible bits : uint64 {
READ = 0x1;
WRITE = 0x2;
EXECUTE = 0x4;
GROWABLE = 0x8;
/// Vendor specific definitions start here
VENDOR_FLAG_0 = 0x10000;
};
type Resource = struct {
buffer zx.koid;
offset uint64;
length uint64;
};
/// Deprecated
type CommandBuffer = struct {
/// Index of the resource containing instructions to start the command buffer.
batch_buffer_resource_index uint32;
/// Starting offset within the resource.
batch_start_offset uint64;
};
type CommandBufferFlags = flexible bits : uint64 {
/// Vendor specific definitions start here
VENDOR_FLAG_0 = 0x10000;
};
type CommandBuffer2 = struct {
/// Index of the resource containing instructions to start the command buffer.
batch_buffer_resource_index uint32;
/// Starting offset within the resource.
batch_start_offset uint64;
/// Flags.
flags CommandBufferFlags;
};
/// 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 PerfCountPoolId = uint64;
type ResultFlags = strict bits {
/// This bit is set in result_flags if the performance counters missed some samples, e.g. due to
/// the GPU being in protected mode for part of the time.
DISCONTINUITY = 1;
};
type BufferOffset = struct {
buffer_id zx.koid;
offset uint64;
size uint64;
};
/// If a system driver error occurs, the connection will be closed and a Status sent via epitaph.
/// If negative, the Epitaph represents a Zircon error.
protocol Primary {
/// Imports an object for use in the system driver.
ImportObject(resource struct {
object zx.handle;
object_type ObjectType;
});
/// Destroys the object with `object_id` within this connection.
ReleaseObject(struct {
object_id zx.koid;
object_type ObjectType;
});
/// Creates context `context_id`.
CreateContext(struct {
context_id uint32;
});
/// Destroys context `context_id`.
DestroyContext(struct {
context_id uint32;
});
/// Deprecated:
/// Submits a command buffer for execution on the GPU, with associated resources.
ExecuteCommandBufferWithResources(struct {
context_id uint32;
command_buffer CommandBuffer;
resources vector<Resource>:MAX;
wait_semaphores vector<zx.koid>:MAX;
signal_semaphores vector<zx.koid>:MAX;
});
/// Submits a command buffer for execution on the GPU, with associated resources.
ExecuteCommandBufferWithResources2(struct {
context_id uint32;
command_buffer CommandBuffer2;
resources vector<Resource>:MAX;
wait_semaphores vector<zx.koid>:MAX;
signal_semaphores vector<zx.koid>:MAX;
});
/// Submits a series of commands for execution on the GPU without using a command buffer.
ExecuteImmediateCommands(struct {
context_id uint32;
command_data bytes:MAX_IMMEDIATE_COMMANDS_DATA_SIZE;
semaphores vector<zx.koid>:MAX;
});
/// Incurs a round-trip to the system driver, used to ensure all previous messages are seen.
Sync() -> ();
/// Maps `page_count` pages of `buffer` from `page_offset` onto the GPU in the connection's
/// address space at `gpu_va`. `flags` is a set of flags from `MAGMA_GPU_MAP_FLAGS` that
/// specify how the GPU can access the buffer.
MapBufferGpu(struct {
buffer_id zx.koid;
gpu_va uint64;
page_offset uint64;
page_count uint64;
flags MapFlags;
});
/// Releases the mapping at `gpu_va` from the GPU.
/// Buffers will also be implicitly unmapped when released.
UnmapBufferGpu(struct {
buffer_id zx.koid;
gpu_va uint64;
});
/// DEPRECATED and replaced by BufferOp.POPULATE_TABLES. Ensures that `page_count` pages
/// starting at `page_offset` from the beginning of the buffer are backed by physical memory.
@deprecated
CommitBuffer(struct {
buffer_id zx.koid;
page_offset uint64;
page_count uint64;
});
/// Perform an operation on a range of the buffer, starting at `start_bytes` and `length` bytes
/// long.
BufferRangeOp(struct {
buffer_id zx.koid;
op BufferOp;
start_bytes uint64;
length uint64;
});
/// Tries to enable performance counter FIDL messages. To be successful, |access_token| must
/// have been returned by PerformanceCounterAccess.GetPerformanceCountToken() from the matching
/// device.
AccessPerformanceCounters(resource struct {
access_token zx.handle:EVENT;
});
/// Returns true if any AccessPerformanceCounters message has succeeded.
IsPerformanceCounterAccessEnabled() -> (struct {
enabled bool;
});
/// Enables the events OnNotifyMessagesConsumed and OnNotifyMemoryImported.
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) <= Max (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.
-> 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) <= Max (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.
-> OnNotifyMemoryImported(struct {
bytes uint64;
});
/// Enables a set of performance counters (the precise definition depends on the GPU driver).
/// 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 AccessPerformanceCounters before calling this method.
EnablePerformanceCounters(struct {
counters vector<uint64>:64;
});
/// Creates a pool of buffers that performance counters can be dumped into. |pool| can be an
/// arbitrary integer that's currently not in use. Performance counter access must have been
/// enabled using AccessPerformanceCounters before calling this method.
CreatePerformanceCounterBufferPool(resource struct {
pool PerfCountPoolId;
event_channel server_end:PerformanceCounterEvents;
});
/// Releases a pool of performance counter buffers. Performance counter access must have been
/// enabled using AccessPerformanceCounters before calling this method.
ReleasePerformanceCounterBufferPool(struct {
pool PerfCountPoolId;
});
/// Adds set of a offsets into buffers to the pool. |offsets[n].buffer_id| is the koid 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
/// |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 AccessPerformanceCounters
/// before calling this method.
AddPerformanceCounterBufferOffsetsToPool(struct {
pool PerfCountPoolId;
offsets vector<BufferOffset>:64;
});
/// Removes every offset of a buffer from the pool. Once this is 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
/// AccessPerformanceCounters before calling this method.
RemovePerformanceCounterBufferFromPool(struct {
pool PerfCountPoolId;
buffer_id zx.koid;
});
/// 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 AccessPerformanceCounters before calling this method.
DumpPerformanceCounters(struct {
pool PerfCountPoolId;
trigger_id uint32;
});
/// 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 AccessPerformanceCounters
/// before calling this method.
ClearPerformanceCounters(struct {
counters vector<uint64>:64;
});
};
/// This protocol is implemented by ZX_PROTOCOL_GPU_PERFORMANCE_COUNTERS devices.
protocol PerformanceCounterAccess {
/// This access token is not used as an event, but is instead passed to
/// Primary.EnablePerformanceCounterAccess.
GetPerformanceCountToken() -> (resource struct {
access_token zx.handle:EVENT;
});
};
protocol PerformanceCounterEvents {
/// Signals that a performance counter buffer has data. These will be output in the order of
/// when the reads are completed.
-> OnPerformanceCounterReadCompleted(struct {
trigger_id uint32;
buffer_id zx.koid;
buffer_offset uint32;
timestamp zx.time;
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.
protocol DependencyInjection {
/// Provides a `fuchsia.memorypressure.Provider` implementation to the MSD.
SetMemoryPressureProvider(resource struct {
provider client_end:fuchsia.memorypressure.Provider;
});
};