summaryrefslogtreecommitdiff
path: root/libdrm
diff options
context:
space:
mode:
Diffstat (limited to 'libdrm')
-rw-r--r--libdrm/Makefile.am4
-rw-r--r--libdrm/dri_bufmgr.c4
-rw-r--r--libdrm/dri_bufmgr.h8
-rw-r--r--libdrm/intel/Makefile.am1
-rw-r--r--libdrm/intel/intel_bufmgr.h35
-rw-r--r--libdrm/intel/intel_bufmgr_fake.c64
-rw-r--r--libdrm/intel/intel_bufmgr_gem.c142
-rw-r--r--libdrm/libdrm_lists.h87
-rw-r--r--libdrm/xf86drm.c43
-rw-r--r--libdrm/xf86drm.h2
10 files changed, 313 insertions, 77 deletions
diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am
index 624f6ffb..c6d66732 100644
--- a/libdrm/Makefile.am
+++ b/libdrm/Makefile.am
@@ -26,10 +26,10 @@ libdrm_la_LDFLAGS = -version-number 2:3:0 -no-undefined
AM_CFLAGS = -I$(top_srcdir)/shared-core
libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \
- xf86drmMode.c dri_bufmgr.c
+ xf86drmMode.c dri_bufmgr.c libdrm_lists.h
libdrm_la_LIBADD = intel/libdrm_intel.la
libdrmincludedir = ${includedir}
-libdrminclude_HEADERS = xf86drm.h xf86mm.h xf86drmMode.h dri_bufmgr.h
+libdrminclude_HEADERS = xf86drm.h xf86drmMode.h dri_bufmgr.h
EXTRA_DIST = ChangeLog TODO
diff --git a/libdrm/dri_bufmgr.c b/libdrm/dri_bufmgr.c
index 7657df61..a6eda3bd 100644
--- a/libdrm/dri_bufmgr.c
+++ b/libdrm/dri_bufmgr.c
@@ -135,7 +135,7 @@ dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug)
}
int
-dri_bufmgr_check_aperture_space(dri_bo *bo)
+dri_bufmgr_check_aperture_space(dri_bo **bo_array, int count)
{
- return bo->bufmgr->check_aperture_space(bo);
+ return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
}
diff --git a/libdrm/dri_bufmgr.h b/libdrm/dri_bufmgr.h
index a5ae6c0f..2005bdc6 100644
--- a/libdrm/dri_bufmgr.h
+++ b/libdrm/dri_bufmgr.h
@@ -58,6 +58,10 @@ struct _dri_bo {
void *virtual;
/** Buffer manager context associated with this buffer object */
dri_bufmgr *bufmgr;
+ /**
+ * MM-specific handle for accessing object
+ */
+ int handle;
};
/**
@@ -146,7 +150,7 @@ struct _dri_bufmgr {
void (*post_submit)(dri_bo *batch_buf);
- int (*check_aperture_space)(dri_bo *bo);
+ int (*check_aperture_space)(dri_bo **bo_array, int count);
int debug; /**< Enables verbose debugging printouts */
};
@@ -169,6 +173,6 @@ void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
void *dri_process_relocs(dri_bo *batch_buf);
void dri_post_process_relocs(dri_bo *batch_buf);
void dri_post_submit(dri_bo *batch_buf);
-int dri_bufmgr_check_aperture_space(dri_bo *bo);
+int dri_bufmgr_check_aperture_space(dri_bo **bo_array, int count);
#endif
diff --git a/libdrm/intel/Makefile.am b/libdrm/intel/Makefile.am
index 111204b1..31a8512a 100644
--- a/libdrm/intel/Makefile.am
+++ b/libdrm/intel/Makefile.am
@@ -24,6 +24,7 @@
AM_CFLAGS = \
$(WARN_CFLAGS) \
+ -I$(top_srcdir)/libdrm \
-I$(top_srcdir)/shared-core
noinst_LTLIBRARIES = libdrm_intel.la
diff --git a/libdrm/intel/intel_bufmgr.h b/libdrm/intel/intel_bufmgr.h
index 1cf0d518..4d335210 100644
--- a/libdrm/intel/intel_bufmgr.h
+++ b/libdrm/intel/intel_bufmgr.h
@@ -61,6 +61,33 @@ struct intel_bufmgr {
int (*emit_reloc)(dri_bo *reloc_buf,
uint32_t read_domains, uint32_t write_domain,
uint32_t delta, uint32_t offset, dri_bo *target);
+ /**
+ * Pin a buffer to the aperture and fix the offset until unpinned
+ *
+ * \param buf Buffer to pin
+ * \param alignment Required alignment for aperture, in bytes
+ */
+ int (*pin) (dri_bo *buf, uint32_t alignment);
+ /**
+ * Unpin a buffer from the aperture, allowing it to be removed
+ *
+ * \param buf Buffer to unpin
+ */
+ int (*unpin) (dri_bo *buf);
+ /**
+ * Ask that the buffer be placed in tiling mode
+ *
+ * \param buf Buffer to set tiling mode for
+ * \param tiling_mode desired, and returned tiling mode
+ */
+ int (*set_tiling) (dri_bo *bo, uint32_t *tiling_mode);
+ /**
+ * Create a visible name for a buffer which can be used by other apps
+ *
+ * \param buf Buffer to create a name for
+ * \param name Returned name
+ */
+ int (*flink) (dri_bo *buf, uint32_t *name);
};
/* intel_bufmgr_gem.c */
@@ -91,5 +118,13 @@ int intel_bo_emit_reloc(dri_bo *reloc_buf,
uint32_t read_domains, uint32_t write_domain,
uint32_t delta, uint32_t offset, dri_bo *target_buf);
+int intel_bo_pin(dri_bo *buf, uint32_t alignment);
+
+int intel_bo_unpin(dri_bo *buf);
+
+int intel_bo_set_tiling(dri_bo *buf, uint32_t *tiling_mode);
+
+int intel_bo_flink(dri_bo *buf, uint32_t *name);
+
#endif /* INTEL_BUFMGR_GEM_H */
diff --git a/libdrm/intel/intel_bufmgr_fake.c b/libdrm/intel/intel_bufmgr_fake.c
index e7ed893f..15da398f 100644
--- a/libdrm/intel/intel_bufmgr_fake.c
+++ b/libdrm/intel/intel_bufmgr_fake.c
@@ -42,6 +42,9 @@
#include "drm.h"
#include "i915_drm.h"
#include "mm.h"
+#include "libdrm_lists.h"
+
+#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
#define DBG(...) do { \
if (bufmgr_fake->bufmgr.debug) \
@@ -147,9 +150,6 @@ typedef struct _bufmgr_fake {
int debug;
int performed_rendering;
-
- /* keep track of the current total size of objects we have relocs for */
- unsigned long current_total_size;
} dri_bufmgr_fake;
typedef struct _dri_bo_fake {
@@ -159,8 +159,8 @@ typedef struct _dri_bo_fake {
const char *name;
unsigned dirty:1;
- unsigned size_accounted:1; /*this buffers size has been accounted against the aperture */
- unsigned card_dirty:1; /* has the card written to this buffer - we make need to copy it back */
+ /** has the card written to this buffer - we make need to copy it back */
+ unsigned card_dirty:1;
unsigned int refcount;
/* Flags may consist of any of the DRM_BO flags, plus
* DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the first two
@@ -179,6 +179,12 @@ typedef struct _dri_bo_fake {
/** relocation list */
struct fake_buffer_reloc *relocs;
int nr_relocs;
+ /**
+ * Total size of the target_bos of this buffer.
+ *
+ * Used for estimation in check_aperture.
+ */
+ unsigned int child_size;
struct block *block;
void *backing_store;
@@ -189,8 +195,6 @@ typedef struct _dri_bo_fake {
static int clear_fenced(dri_bufmgr_fake *bufmgr_fake,
unsigned int fence_cookie);
-static int dri_fake_check_aperture_space(dri_bo *bo);
-
#define MAXFENCE 0x7fffffff
static int FENCE_LTE( unsigned a, unsigned b )
@@ -855,9 +859,6 @@ dri_fake_bo_validate(dri_bo *bo)
return 0;
}
- /* reset size accounted */
- bo_fake->size_accounted = 0;
-
/* Allocate the card memory */
if (!bo_fake->block && !evict_and_alloc_block(bo)) {
bufmgr_fake->fail = 1;
@@ -941,8 +942,6 @@ dri_fake_emit_reloc(dri_bo *reloc_buf,
assert(reloc_buf);
assert(target_buf);
- assert(target_fake->is_static || target_fake->size_accounted);
-
if (reloc_fake->relocs == NULL) {
reloc_fake->relocs = malloc(sizeof(struct fake_buffer_reloc) *
MAX_RELOCS);
@@ -954,6 +953,9 @@ dri_fake_emit_reloc(dri_bo *reloc_buf,
dri_bo_reference(target_buf);
+ if (!target_fake->is_static)
+ reloc_fake->child_size += ALIGN(target_buf->size, target_fake->alignment);
+
r->target_buf = target_buf;
r->offset = offset;
r->last_target_offset = target_buf->offset;
@@ -1079,7 +1081,6 @@ dri_fake_process_relocs(dri_bo *batch_buf)
assert(ret == 0);
- bufmgr_fake->current_total_size = 0;
return NULL;
}
@@ -1117,26 +1118,39 @@ dri_fake_post_submit(dri_bo *batch_buf)
dri_bo_fake_post_submit(batch_buf);
}
+/**
+ * Return an error if the list of BOs will exceed the aperture size.
+ *
+ * This is a rough guess and likely to fail, as during the validate sequence we
+ * may place a buffer in an inopportune spot early on and then fail to fit
+ * a set smaller than the aperture.
+ */
static int
-dri_fake_check_aperture_space(dri_bo *bo)
+dri_fake_check_aperture_space(dri_bo **bo_array, int count)
{
- dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
- dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
- unsigned int sz;
+ dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo_array[0]->bufmgr;
+ unsigned int sz = 0;
+ int i;
- sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1);
+ for (i = 0; i < count; i++) {
+ dri_bo_fake *bo_fake = (dri_bo_fake *)bo_array[i];
- if (bo_fake->size_accounted || bo_fake->is_static)
- return 0;
+ if (bo_fake == NULL)
+ continue;
+
+ if (!bo_fake->is_static)
+ sz += ALIGN(bo_array[i]->size, bo_fake->alignment);
+ sz += bo_fake->child_size;
+ }
- if (bufmgr_fake->current_total_size + sz > bufmgr_fake->size) {
- DBG("check_space: %s bo %d %d overflowed bufmgr size %d\n", bo_fake->name, bo_fake->id, sz, bufmgr_fake->size);
+ if (sz > bufmgr_fake->size) {
+ DBG("check_space: overflowed bufmgr size, %dkb vs %dkb\n",
+ sz / 1024, bufmgr_fake->size / 1024);
return -1;
}
- bufmgr_fake->current_total_size += sz;
- bo_fake->size_accounted = 1;
- DBG("drm_check_space: buf %d, %s %d %d\n", bo_fake->id, bo_fake->name, bo->size, bufmgr_fake->current_total_size);
+ DBG("drm_check_space: sz %dkb vs bufgr %dkb\n", sz / 1024 ,
+ bufmgr_fake->size / 1024);
return 0;
}
diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c
index cdc2a7ac..af20efb2 100644
--- a/libdrm/intel/intel_bufmgr_gem.c
+++ b/libdrm/intel/intel_bufmgr_gem.c
@@ -103,6 +103,11 @@ struct _dri_bo_gem {
const char *name;
/**
+ * Kenel-assigned global name for this object
+ */
+ unsigned int global_name;
+
+ /**
* Index of the buffer within the validation list while preparing a
* batchbuffer execution.
*/
@@ -311,6 +316,7 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CREATE, &create);
bo_gem->gem_handle = create.handle;
+ bo_gem->bo.handle = bo_gem->gem_handle;
if (ret != 0) {
free(bo_gem);
return NULL;
@@ -768,6 +774,84 @@ dri_gem_post_submit(dri_bo *batch_buf)
bufmgr_gem->exec_count = 0;
}
+static int
+dri_gem_pin(dri_bo *bo, uint32_t alignment)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
+ struct drm_i915_gem_pin pin;
+ int ret;
+
+ pin.handle = bo_gem->gem_handle;
+ pin.alignment = alignment;
+
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_PIN, &pin);
+ if (ret != 0)
+ return -errno;
+
+ bo->offset = pin.offset;
+ return 0;
+}
+
+static int
+dri_gem_unpin(dri_bo *bo)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
+ struct drm_i915_gem_unpin unpin;
+ int ret;
+
+ unpin.handle = bo_gem->gem_handle;
+
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_UNPIN, &unpin);
+ if (ret != 0)
+ return -errno;
+
+ return 0;
+}
+
+static int
+dri_gem_set_tiling(dri_bo *bo, uint32_t *tiling_mode)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
+ struct drm_i915_gem_set_tiling set_tiling;
+ int ret;
+
+ set_tiling.handle = bo_gem->gem_handle;
+ set_tiling.tiling_mode = *tiling_mode;
+
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling);
+ if (ret != 0) {
+ *tiling_mode = I915_TILING_NONE;
+ return -errno;
+ }
+
+ *tiling_mode = set_tiling.tiling_mode;
+ return 0;
+}
+
+static int
+dri_gem_flink(dri_bo *bo, uint32_t *name)
+{
+ dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+ dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
+ struct drm_gem_flink flink;
+ int ret;
+
+ if (!bo_gem->global_name) {
+ flink.handle = bo_gem->gem_handle;
+
+ ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink);
+ if (ret != 0)
+ return -errno;
+ bo_gem->global_name = flink.name;
+ }
+
+ *name = bo_gem->global_name;
+ return 0;
+}
+
/**
* Enables unlimited caching of buffer objects for reuse.
*
@@ -790,7 +874,7 @@ intel_bufmgr_gem_enable_reuse(dri_bufmgr *bufmgr)
*
*/
static int
-dri_gem_check_aperture_space(dri_bo *bo)
+dri_gem_check_aperture_space(dri_bo **bo_array, int count)
{
return 0;
}
@@ -832,6 +916,10 @@ intel_bufmgr_gem_init(int fd, int batch_size)
bufmgr_gem->bufmgr.debug = 0;
bufmgr_gem->bufmgr.check_aperture_space = dri_gem_check_aperture_space;
bufmgr_gem->intel_bufmgr.emit_reloc = dri_gem_emit_reloc;
+ bufmgr_gem->intel_bufmgr.pin = dri_gem_pin;
+ bufmgr_gem->intel_bufmgr.unpin = dri_gem_unpin;
+ bufmgr_gem->intel_bufmgr.set_tiling = dri_gem_set_tiling;
+ bufmgr_gem->intel_bufmgr.flink = dri_gem_flink;
/* Initialize the linked lists for BO reuse cache. */
for (i = 0; i < INTEL_GEM_BO_BUCKETS; i++)
bufmgr_gem->cache_bucket[i].tail = &bufmgr_gem->cache_bucket[i].head;
@@ -851,3 +939,55 @@ intel_bo_emit_reloc(dri_bo *reloc_buf,
return intel_bufmgr->emit_reloc(reloc_buf, read_domains, write_domain,
delta, offset, target_buf);
}
+
+int
+intel_bo_pin(dri_bo *bo, uint32_t alignment)
+{
+ struct intel_bufmgr *intel_bufmgr;
+
+ intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1);
+
+ if (intel_bufmgr->pin)
+ return intel_bufmgr->pin(bo, alignment);
+
+ return 0;
+}
+
+int
+intel_bo_unpin(dri_bo *bo)
+{
+ struct intel_bufmgr *intel_bufmgr;
+
+ intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1);
+
+ if (intel_bufmgr->unpin)
+ return intel_bufmgr->unpin(bo);
+
+ return 0;
+}
+
+int intel_bo_set_tiling(dri_bo *bo, uint32_t *tiling_mode)
+{
+ struct intel_bufmgr *intel_bufmgr;
+
+ intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1);
+
+ if (intel_bufmgr->set_tiling)
+ return intel_bufmgr->set_tiling (bo, tiling_mode);
+
+ *tiling_mode = I915_TILING_NONE;
+ return 0;
+}
+
+int intel_bo_flink(dri_bo *bo, uint32_t *name)
+{
+ struct intel_bufmgr *intel_bufmgr;
+
+ intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1);
+
+ if (intel_bufmgr->flink)
+ return intel_bufmgr->flink (bo, name);
+
+ return -ENODEV;
+}
+
diff --git a/libdrm/libdrm_lists.h b/libdrm/libdrm_lists.h
new file mode 100644
index 00000000..8e23991f
--- /dev/null
+++ b/libdrm/libdrm_lists.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+
+/*
+ * List macros heavily inspired by the Linux kernel
+ * list handling. No list looping yet.
+ */
+
+typedef struct _drmMMListHead
+{
+ struct _drmMMListHead *prev;
+ struct _drmMMListHead *next;
+} drmMMListHead;
+
+#define DRMINITLISTHEAD(__item) \
+ do{ \
+ (__item)->prev = (__item); \
+ (__item)->next = (__item); \
+ } while (0)
+
+#define DRMLISTADD(__item, __list) \
+ do { \
+ (__item)->prev = (__list); \
+ (__item)->next = (__list)->next; \
+ (__list)->next->prev = (__item); \
+ (__list)->next = (__item); \
+ } while (0)
+
+#define DRMLISTADDTAIL(__item, __list) \
+ do { \
+ (__item)->next = (__list); \
+ (__item)->prev = (__list)->prev; \
+ (__list)->prev->next = (__item); \
+ (__list)->prev = (__item); \
+ } while(0)
+
+#define DRMLISTDEL(__item) \
+ do { \
+ (__item)->prev->next = (__item)->next; \
+ (__item)->next->prev = (__item)->prev; \
+ } while(0)
+
+#define DRMLISTDELINIT(__item) \
+ do { \
+ (__item)->prev->next = (__item)->next; \
+ (__item)->next->prev = (__item)->prev; \
+ (__item)->next = (__item); \
+ (__item)->prev = (__item); \
+ } while(0)
+
+#define DRMLISTENTRY(__type, __item, __field) \
+ ((__type *)(((char *) (__item)) - offsetof(__type, __field)))
+
+#define DRMLISTEMPTY(__item) ((__item)->next == (__item))
+
+#define DRMLISTFOREACHSAFE(__item, __temp, __list) \
+ for ((__item) = (__list)->next, (__temp) = (__item)->next; \
+ (__item) != (__list); \
+ (__item) = (__temp), (__temp) = (__item)->next)
+
+#define DRMLISTFOREACHSAFEREVERSE(__item, __temp, __list) \
+ for ((__item) = (__list)->prev, (__temp) = (__item)->prev; \
+ (__item) != (__list); \
+ (__item) = (__temp), (__temp) = (__item)->prev)
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index 1fd3a697..64765339 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -2356,49 +2356,6 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
return 0;
}
-
-#define DRM_IOCTL_TIMEOUT_USEC 3000000UL
-
-static unsigned long
-drmTimeDiff(struct timeval *now, struct timeval *then)
-{
- uint64_t val;
-
- val = now->tv_sec - then->tv_sec;
- val *= 1000000LL;
- val += now->tv_usec;
- val -= then->tv_usec;
-
- return (unsigned long) val;
-}
-
-static int
-drmIoctlTimeout(int fd, unsigned long request, void *argp)
-{
- int haveThen = 0;
- struct timeval then, now;
- int ret;
-
- do {
- ret = drmIoctl(fd, request, argp);
- if (ret != 0 && errno == EAGAIN) {
- if (!haveThen) {
- gettimeofday(&then, NULL);
- haveThen = 1;
- }
- gettimeofday(&now, NULL);
- }
- } while (ret != 0 && errno == EAGAIN &&
- drmTimeDiff(&now, &then) < DRM_IOCTL_TIMEOUT_USEC);
-
- if (ret != 0)
- return ((errno == EAGAIN) ? -EBUSY : -errno);
-
- return 0;
-}
-
-
-
#define DRM_MAX_FDS 16
static struct {
char *BusID;
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h
index b29b3e5d..584d2a41 100644
--- a/libdrm/xf86drm.h
+++ b/libdrm/xf86drm.h
@@ -664,6 +664,4 @@ extern void drmMsg(const char *format, ...);
extern int drmSetMaster(int fd);
extern int drmDropMaster(int fd);
-#include "xf86mm.h"
-
#endif