17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2011 Intel Corporation
37ec681f3Smrg * Copyright © 2021 NVIDIA Corporation
47ec681f3Smrg *
57ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
67ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
77ec681f3Smrg * to deal in the Software without restriction, including without limitation
87ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
97ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
107ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
117ec681f3Smrg *
127ec681f3Smrg * The above copyright notice and this permission notice (including the next
137ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
147ec681f3Smrg * Software.
157ec681f3Smrg *
167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
177ec681f3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
187ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
197ec681f3Smrg * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
207ec681f3Smrg * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
217ec681f3Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
227ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
237ec681f3Smrg * DEALINGS IN THE SOFTWARE.
247ec681f3Smrg *
257ec681f3Smrg * Authors:
267ec681f3Smrg *    Benjamin Franzke <benjaminfranzke@googlemail.com>
277ec681f3Smrg *    James Jones <jajones@nvidia.com>
287ec681f3Smrg */
297ec681f3Smrg
307ec681f3Smrg#ifndef GBM_BACKEND_ABI_H_
317ec681f3Smrg#define GBM_BACKEND_ABI_H_
327ec681f3Smrg
337ec681f3Smrg#include "gbm.h"
347ec681f3Smrg
357ec681f3Smrg/**
367ec681f3Smrg * \file gbm_backend_abi.h
377ec681f3Smrg * \brief ABI between the GBM loader and its backends
387ec681f3Smrg */
397ec681f3Smrg
407ec681f3Smrgstruct gbm_backend_desc;
417ec681f3Smrg
427ec681f3Smrg/**
437ec681f3Smrg * The GBM backend interface version defined by this file.
447ec681f3Smrg *
457ec681f3Smrg * The GBM device interface version must be incremented whenever the structures
467ec681f3Smrg * defined in this file are modified. To preserve ABI compatibility with
477ec681f3Smrg * backends that support only older versions, modifications to this file must
487ec681f3Smrg * consist only of appending new fields to the end of the structures defined in
497ec681f3Smrg * it, defining new structures, or declaring new exported functions or global
507ec681f3Smrg * variables.
517ec681f3Smrg *
527ec681f3Smrg * Note this version applies to ALL structures in this file, not just the core,
537ec681f3Smrg * backend, and device structures which contain it explicitly. Buffer objects,
547ec681f3Smrg * surfaces, and any other new structures introduced to this file are also part
557ec681f3Smrg * of the backend ABI. The ABI version of an instance of any object in this file
567ec681f3Smrg * is defined as the minimum of the version of the backend associated with the
577ec681f3Smrg * object instance and the loader's core object version. Hence, any new objects
587ec681f3Smrg * added to this file should contain either a reference to an existing object
597ec681f3Smrg * defined here, or an explicit version field.
607ec681f3Smrg *
617ec681f3Smrg * A few examples of object versions:
627ec681f3Smrg *
637ec681f3Smrg * Backend ABI version: 0
647ec681f3Smrg * Core ABI version: 3
657ec681f3Smrg * ABI version of a device created by the backend: 0
667ec681f3Smrg *
677ec681f3Smrg * Backend ABI version: 2
687ec681f3Smrg * Core ABI version: 1
697ec681f3Smrg * ABI version of a surface created by a device from the backend: 1
707ec681f3Smrg *
717ec681f3Smrg * Backend ABI version: 4
727ec681f3Smrg * Core ABI version: 4
737ec681f3Smrg * ABI version of a buffer object created by a device from the backend: 4
747ec681f3Smrg */
757ec681f3Smrg#define GBM_BACKEND_ABI_VERSION 1
767ec681f3Smrg
777ec681f3Smrg/**
787ec681f3Smrg * GBM device interface corresponding to GBM_BACKEND_ABI_VERSION = 0
797ec681f3Smrg *
807ec681f3Smrg * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_bo_v1, increment
817ec681f3Smrg * GBM_BACKEND_ABI_VERSION, and append gbm_bo_v1 to gbm_bo.
827ec681f3Smrg */
837ec681f3Smrgstruct gbm_device_v0 {
847ec681f3Smrg   const struct gbm_backend_desc *backend_desc;
857ec681f3Smrg
867ec681f3Smrg   /**
877ec681f3Smrg    * The version of the GBM backend interface supported by this device and its
887ec681f3Smrg    * child objects. This may be less than the maximum version supported by the
897ec681f3Smrg    * GBM loader if the device was created by an older backend, or less than the
907ec681f3Smrg    * maximum version supported by the backend if the device was created by an
917ec681f3Smrg    * older loader. In other words, this will be:
927ec681f3Smrg    *
937ec681f3Smrg    *   MIN(backend GBM interface version, loader GBM interface version)
947ec681f3Smrg    *
957ec681f3Smrg    * It is the backend's responsibility to assign this field the value passed
967ec681f3Smrg    * in by the GBM loader to the backend's create_device function. The GBM
977ec681f3Smrg    * loader will pre-clamp the value based on the loader version and the
987ec681f3Smrg    * version reported by the backend in its gbm_backend_v0::backend_version
997ec681f3Smrg    * field. It is the loader's responsibility to respect this version when
1007ec681f3Smrg    * directly accessing a device instance or any child objects instantiated by
1017ec681f3Smrg    * a device instance.
1027ec681f3Smrg    */
1037ec681f3Smrg   uint32_t backend_version;
1047ec681f3Smrg
1057ec681f3Smrg   int fd;
1067ec681f3Smrg   const char *name;
1077ec681f3Smrg
1087ec681f3Smrg   void (*destroy)(struct gbm_device *gbm);
1097ec681f3Smrg   int (*is_format_supported)(struct gbm_device *gbm,
1107ec681f3Smrg                              uint32_t format,
1117ec681f3Smrg                              uint32_t usage);
1127ec681f3Smrg   int (*get_format_modifier_plane_count)(struct gbm_device *device,
1137ec681f3Smrg                                          uint32_t format,
1147ec681f3Smrg                                          uint64_t modifier);
1157ec681f3Smrg
1167ec681f3Smrg   /**
1177ec681f3Smrg    * Since version 1, usage is properly populated when modifiers are
1187ec681f3Smrg    * supplied. Version 0 always set usage to 0 in this case.
1197ec681f3Smrg    */
1207ec681f3Smrg   struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
1217ec681f3Smrg                               uint32_t width, uint32_t height,
1227ec681f3Smrg                               uint32_t format,
1237ec681f3Smrg                               uint32_t usage,
1247ec681f3Smrg                               const uint64_t *modifiers,
1257ec681f3Smrg                               const unsigned int count);
1267ec681f3Smrg   struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type,
1277ec681f3Smrg                               void *buffer, uint32_t usage);
1287ec681f3Smrg   void *(*bo_map)(struct gbm_bo *bo,
1297ec681f3Smrg                               uint32_t x, uint32_t y,
1307ec681f3Smrg                               uint32_t width, uint32_t height,
1317ec681f3Smrg                               uint32_t flags, uint32_t *stride,
1327ec681f3Smrg                               void **map_data);
1337ec681f3Smrg   void (*bo_unmap)(struct gbm_bo *bo, void *map_data);
1347ec681f3Smrg   int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data);
1357ec681f3Smrg   int (*bo_get_fd)(struct gbm_bo *bo);
1367ec681f3Smrg   int (*bo_get_planes)(struct gbm_bo *bo);
1377ec681f3Smrg   union gbm_bo_handle (*bo_get_handle)(struct gbm_bo *bo, int plane);
1387ec681f3Smrg   int (*bo_get_plane_fd)(struct gbm_bo *bo, int plane);
1397ec681f3Smrg   uint32_t (*bo_get_stride)(struct gbm_bo *bo, int plane);
1407ec681f3Smrg   uint32_t (*bo_get_offset)(struct gbm_bo *bo, int plane);
1417ec681f3Smrg   uint64_t (*bo_get_modifier)(struct gbm_bo *bo);
1427ec681f3Smrg   void (*bo_destroy)(struct gbm_bo *bo);
1437ec681f3Smrg
1447ec681f3Smrg   /**
1457ec681f3Smrg    * Since version 1, flags are properly populated when modifiers are
1467ec681f3Smrg    * supplied. Version 0 always set flags to 0 in this case.
1477ec681f3Smrg    */
1487ec681f3Smrg   struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
1497ec681f3Smrg                                         uint32_t width, uint32_t height,
1507ec681f3Smrg                                         uint32_t format, uint32_t flags,
1517ec681f3Smrg                                         const uint64_t *modifiers,
1527ec681f3Smrg                                         const unsigned count);
1537ec681f3Smrg   struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface);
1547ec681f3Smrg   void (*surface_release_buffer)(struct gbm_surface *surface,
1557ec681f3Smrg                                  struct gbm_bo *bo);
1567ec681f3Smrg   int (*surface_has_free_buffers)(struct gbm_surface *surface);
1577ec681f3Smrg   void (*surface_destroy)(struct gbm_surface *surface);
1587ec681f3Smrg};
1597ec681f3Smrg
1607ec681f3Smrg/**
1617ec681f3Smrg * The device used for the memory allocation.
1627ec681f3Smrg *
1637ec681f3Smrg * The members of this structure should be not accessed directly
1647ec681f3Smrg *
1657ec681f3Smrg * To modify this structure, introduce a new gbm_device_v<N> structure, add it
1667ec681f3Smrg * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
1677ec681f3Smrg */
1687ec681f3Smrgstruct gbm_device {
1697ec681f3Smrg   /* Hack to make a gbm_device detectable by its first element. */
1707ec681f3Smrg   struct gbm_device *(*dummy)(int);
1717ec681f3Smrg   struct gbm_device_v0 v0;
1727ec681f3Smrg};
1737ec681f3Smrg
1747ec681f3Smrg/**
1757ec681f3Smrg * GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0
1767ec681f3Smrg *
1777ec681f3Smrg * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_bo_v1, increment
1787ec681f3Smrg * GBM_BACKEND_ABI_VERSION, and append gbm_bo_v1 to gbm_bo.
1797ec681f3Smrg */
1807ec681f3Smrgstruct gbm_bo_v0 {
1817ec681f3Smrg   uint32_t width;
1827ec681f3Smrg   uint32_t height;
1837ec681f3Smrg   uint32_t stride;
1847ec681f3Smrg   uint32_t format;
1857ec681f3Smrg   union gbm_bo_handle  handle;
1867ec681f3Smrg   void *user_data;
1877ec681f3Smrg   void (*destroy_user_data)(struct gbm_bo *, void *);
1887ec681f3Smrg};
1897ec681f3Smrg
1907ec681f3Smrg/**
1917ec681f3Smrg * The allocated buffer object.
1927ec681f3Smrg *
1937ec681f3Smrg * The members in this structure should not be accessed directly.
1947ec681f3Smrg *
1957ec681f3Smrg * To modify this structure, introduce a new gbm_bo_v<N> structure, add it to
1967ec681f3Smrg * the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
1977ec681f3Smrg */
1987ec681f3Smrgstruct gbm_bo {
1997ec681f3Smrg   struct gbm_device *gbm;
2007ec681f3Smrg   struct gbm_bo_v0 v0;
2017ec681f3Smrg};
2027ec681f3Smrg
2037ec681f3Smrg/**
2047ec681f3Smrg * GBM surface interface corresponding to GBM_BACKEND_ABI_VERSION = 0
2057ec681f3Smrg *
2067ec681f3Smrg * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_surface_v1, increment
2077ec681f3Smrg * GBM_BACKEND_ABI_VERSION, and append gbm_surface_v1 to gbm_surface.
2087ec681f3Smrg */
2097ec681f3Smrgstruct gbm_surface_v0 {
2107ec681f3Smrg   uint32_t width;
2117ec681f3Smrg   uint32_t height;
2127ec681f3Smrg   uint32_t format;
2137ec681f3Smrg   uint32_t flags;
2147ec681f3Smrg   struct {
2157ec681f3Smrg      uint64_t *modifiers;
2167ec681f3Smrg      unsigned count;
2177ec681f3Smrg   };
2187ec681f3Smrg};
2197ec681f3Smrg
2207ec681f3Smrg/**
2217ec681f3Smrg * An allocated GBM surface.
2227ec681f3Smrg *
2237ec681f3Smrg * To modify this structure, introduce a new gbm_surface_v<N> structure, add it
2247ec681f3Smrg * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
2257ec681f3Smrg */
2267ec681f3Smrgstruct gbm_surface {
2277ec681f3Smrg   struct gbm_device *gbm;
2287ec681f3Smrg   struct gbm_surface_v0 v0;
2297ec681f3Smrg};
2307ec681f3Smrg
2317ec681f3Smrg/**
2327ec681f3Smrg * GBM backend interfaces corresponding to GBM_BACKEND_ABI_VERSION = 0
2337ec681f3Smrg *
2347ec681f3Smrg * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_backend_v1, increment
2357ec681f3Smrg * GBM_BACKEND_ABI_VERSION, append gbm_backend_v1 to gbm_backend.
2367ec681f3Smrg */
2377ec681f3Smrgstruct gbm_backend_v0 {
2387ec681f3Smrg   /**
2397ec681f3Smrg    * The version of the GBM backend interface supported by this backend. This
2407ec681f3Smrg    * is set by the backend itself, and may be greater or less than the version
2417ec681f3Smrg    * supported by the loader. It is the responsibility of the GBM loader to
2427ec681f3Smrg    * respect this version when accessing fields in this structure.
2437ec681f3Smrg    */
2447ec681f3Smrg   uint32_t backend_version;
2457ec681f3Smrg
2467ec681f3Smrg   const char *backend_name;
2477ec681f3Smrg   struct gbm_device *(*create_device)(int fd, uint32_t gbm_backend_version);
2487ec681f3Smrg};
2497ec681f3Smrg
2507ec681f3Smrg/**
2517ec681f3Smrg * The interface exposed by an external GBM backend.
2527ec681f3Smrg *
2537ec681f3Smrg * To modify this structure, introduce a new gbm_backend_v<N> structure, add it
2547ec681f3Smrg * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
2557ec681f3Smrg */
2567ec681f3Smrgstruct gbm_backend {
2577ec681f3Smrg   struct gbm_backend_v0 v0;
2587ec681f3Smrg};
2597ec681f3Smrg
2607ec681f3Smrg/**
2617ec681f3Smrg * GBM interfaces exposed to GBM backends at GBM_BACKEND_ABI_VERSION >= 0
2627ec681f3Smrg *
2637ec681f3Smrg * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_core_v1, increment
2647ec681f3Smrg * GBM_BACKEND_ABI_VERSION, and append gbm_core_v1 to gbm_backend.
2657ec681f3Smrg */
2667ec681f3Smrgstruct gbm_core_v0 {
2677ec681f3Smrg   /**
2687ec681f3Smrg    * The version of the GBM backend interface supported by the GBM loader. This
2697ec681f3Smrg    * is set by the loader, and may be greater or less than the version
2707ec681f3Smrg    * supported by a given backend. It is the responsibility of the backend to
2717ec681f3Smrg    * respect this version when accessing fields in this structure and other
2727ec681f3Smrg    * structures allocated or modified by the loader.
2737ec681f3Smrg    */
2747ec681f3Smrg   uint32_t core_version;
2757ec681f3Smrg
2767ec681f3Smrg   uint32_t (*format_canonicalize)(uint32_t gbm_format);
2777ec681f3Smrg};
2787ec681f3Smrg
2797ec681f3Smrg/**
2807ec681f3Smrg * The interface exposed by the GBM core/loader code to GBM backends.
2817ec681f3Smrg *
2827ec681f3Smrg * To modify this structure, introduce a new gbm_core_v<N> structure, add it
2837ec681f3Smrg * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
2847ec681f3Smrg */
2857ec681f3Smrgstruct gbm_core {
2867ec681f3Smrg   struct gbm_core_v0 v0;
2877ec681f3Smrg};
2887ec681f3Smrg
2897ec681f3Smrg/**
2907ec681f3Smrg * The entrypoint an external GBM backend exports.
2917ec681f3Smrg *
2927ec681f3Smrg * Prior to creating any devices using the backend, GBM will look up and call
2937ec681f3Smrg * this function to request the backend's interface and convey the loader's
2947ec681f3Smrg * version and exported interface to the backend.
2957ec681f3Smrg *
2967ec681f3Smrg * DO NOT MODIFY THIS FUNCTION NAME OR PROTOTYPE. It must remain unchanged to
2977ec681f3Smrg * preserve backwards compatibility with existing GBM backends.
2987ec681f3Smrg */
2997ec681f3Smrg#define GBM_GET_BACKEND_PROC gbmint_get_backend
3007ec681f3Smrg#define _GBM_MKSTRX(s) _GBM_MKSTR(s)
3017ec681f3Smrg#define _GBM_MKSTR(s) #s
3027ec681f3Smrg#define GBM_GET_BACKEND_PROC_NAME _GBM_MKSTRX(GBM_GET_BACKEND_PROC)
3037ec681f3Smrgtypedef const struct gbm_backend *(*GBM_GET_BACKEND_PROC_PTR)(const struct gbm_core *gbm_core);
3047ec681f3Smrg
3057ec681f3Smrg#endif
306