• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #ifdef DRV_I915
8 
9 #include <assert.h>
10 #include <errno.h>
11 #include <i915_drm.h>
12 #include <stdbool.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/mman.h>
16 #include <xf86drm.h>
17 
18 #include "drv_priv.h"
19 #include "helpers.h"
20 #include "util.h"
21 
22 #define I915_CACHELINE_SIZE 64
23 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1)
24 
25 static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888,    DRM_FORMAT_ARGB1555,
26 						  DRM_FORMAT_ARGB8888,    DRM_FORMAT_BGR888,
27 						  DRM_FORMAT_RGB565,      DRM_FORMAT_XBGR2101010,
28 						  DRM_FORMAT_XBGR8888,    DRM_FORMAT_XRGB1555,
29 						  DRM_FORMAT_XRGB2101010, DRM_FORMAT_XRGB8888 };
30 
31 static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8,
32 							    DRM_FORMAT_UYVY, DRM_FORMAT_YUYV };
33 
34 static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID,
35 						   DRM_FORMAT_NV12 };
36 
37 struct i915_device {
38 	uint32_t gen;
39 	int32_t has_llc;
40 };
41 
i915_get_gen(int device_id)42 static uint32_t i915_get_gen(int device_id)
43 {
44 	const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE,
45 				      0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 };
46 	unsigned i;
47 	for (i = 0; i < ARRAY_SIZE(gen3_ids); i++)
48 		if (gen3_ids[i] == device_id)
49 			return 3;
50 
51 	return 4;
52 }
53 
54 /*
55  * We allow allocation of ARGB formats for SCANOUT if the corresponding XRGB
56  * formats supports it. It's up to the caller (chrome ozone) to ultimately not
57  * scan out ARGB if the display controller only supports XRGB, but we'll allow
58  * the allocation of the bo here.
59  */
format_compatible(const struct combination * combo,uint32_t format)60 static bool format_compatible(const struct combination *combo, uint32_t format)
61 {
62 	if (combo->format == format)
63 		return true;
64 
65 	switch (format) {
66 	case DRM_FORMAT_XRGB8888:
67 		return combo->format == DRM_FORMAT_ARGB8888;
68 	case DRM_FORMAT_XBGR8888:
69 		return combo->format == DRM_FORMAT_ABGR8888;
70 	case DRM_FORMAT_RGBX8888:
71 		return combo->format == DRM_FORMAT_RGBA8888;
72 	case DRM_FORMAT_BGRX8888:
73 		return combo->format == DRM_FORMAT_BGRA8888;
74 	default:
75 		return false;
76 	}
77 }
78 
i915_add_kms_item(struct driver * drv,const struct kms_item * item)79 static int i915_add_kms_item(struct driver *drv, const struct kms_item *item)
80 {
81 	uint32_t i;
82 	struct combination *combo;
83 
84 	/*
85 	 * Older hardware can't scanout Y-tiled formats. Newer devices can, and
86 	 * report this functionality via format modifiers.
87 	 */
88 	for (i = 0; i < drv_array_size(drv->combos); i++) {
89 		combo = (struct combination *)drv_array_at_idx(drv->combos, i);
90 		if (!format_compatible(combo, item->format))
91 			continue;
92 
93 		if (item->modifier == DRM_FORMAT_MOD_LINEAR &&
94 		    combo->metadata.tiling == I915_TILING_X) {
95 			/*
96 			 * FIXME: drv_query_kms() does not report the available modifiers
97 			 * yet, but we know that all hardware can scanout from X-tiled
98 			 * buffers, so let's add this to our combinations, except for
99 			 * cursor, which must not be tiled.
100 			 */
101 			combo->use_flags |= item->use_flags & ~BO_USE_CURSOR;
102 		}
103 
104 		/* If we can scanout NV12, we support all tiling modes. */
105 		if (item->format == DRM_FORMAT_NV12)
106 			combo->use_flags |= item->use_flags;
107 
108 		if (combo->metadata.modifier == item->modifier)
109 			combo->use_flags |= item->use_flags;
110 	}
111 
112 	return 0;
113 }
114 
i915_add_combinations(struct driver * drv)115 static int i915_add_combinations(struct driver *drv)
116 {
117 	int ret;
118 	uint32_t i;
119 	struct drv_array *kms_items;
120 	struct format_metadata metadata;
121 	uint64_t render_use_flags, texture_use_flags;
122 
123 	render_use_flags = BO_USE_RENDER_MASK;
124 	texture_use_flags = BO_USE_TEXTURE_MASK;
125 
126 	metadata.tiling = I915_TILING_NONE;
127 	metadata.priority = 1;
128 	metadata.modifier = DRM_FORMAT_MOD_LINEAR;
129 
130 	drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
131 			     &metadata, render_use_flags);
132 
133 	drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats),
134 			     &metadata, texture_use_flags);
135 
136 	drv_add_combinations(drv, tileable_texture_source_formats,
137 			     ARRAY_SIZE(tileable_texture_source_formats), &metadata,
138 			     texture_use_flags);
139 
140 	drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT);
141 	drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT);
142 
143 	/* IPU3 camera ISP supports only NV12 output. */
144 	drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
145 			       BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
146 	/*
147 	 * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
148 	 * from camera.
149 	 */
150 	drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
151 			       BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
152 
153 	render_use_flags &= ~BO_USE_RENDERSCRIPT;
154 	render_use_flags &= ~BO_USE_SW_WRITE_OFTEN;
155 	render_use_flags &= ~BO_USE_SW_READ_OFTEN;
156 	render_use_flags &= ~BO_USE_LINEAR;
157 
158 	texture_use_flags &= ~BO_USE_RENDERSCRIPT;
159 	texture_use_flags &= ~BO_USE_SW_WRITE_OFTEN;
160 	texture_use_flags &= ~BO_USE_SW_READ_OFTEN;
161 	texture_use_flags &= ~BO_USE_LINEAR;
162 
163 	metadata.tiling = I915_TILING_X;
164 	metadata.priority = 2;
165 	metadata.modifier = I915_FORMAT_MOD_X_TILED;
166 
167 	drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
168 			     &metadata, render_use_flags);
169 
170 	drv_add_combinations(drv, tileable_texture_source_formats,
171 			     ARRAY_SIZE(tileable_texture_source_formats), &metadata,
172 			     texture_use_flags);
173 
174 	metadata.tiling = I915_TILING_Y;
175 	metadata.priority = 3;
176 	metadata.modifier = I915_FORMAT_MOD_Y_TILED;
177 
178 	drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
179 			     &metadata, render_use_flags);
180 
181 	drv_add_combinations(drv, tileable_texture_source_formats,
182 			     ARRAY_SIZE(tileable_texture_source_formats), &metadata,
183 			     texture_use_flags);
184 
185 	/* Support y-tiled NV12 for libva */
186 	const uint32_t nv12_format = DRM_FORMAT_NV12;
187 	drv_add_combinations(drv, &nv12_format, 1, &metadata,
188 			     BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER);
189 
190 	kms_items = drv_query_kms(drv);
191 	if (!kms_items)
192 		return 0;
193 
194 	for (i = 0; i < drv_array_size(kms_items); i++) {
195 		ret = i915_add_kms_item(drv, (struct kms_item *)drv_array_at_idx(kms_items, i));
196 		if (ret) {
197 			drv_array_destroy(kms_items);
198 			return ret;
199 		}
200 	}
201 
202 	drv_array_destroy(kms_items);
203 	return 0;
204 }
205 
i915_align_dimensions(struct bo * bo,uint32_t tiling,uint32_t * stride,uint32_t * aligned_height)206 static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *stride,
207 				 uint32_t *aligned_height)
208 {
209 	struct i915_device *i915 = bo->drv->priv;
210 	uint32_t horizontal_alignment;
211 	uint32_t vertical_alignment;
212 
213 	switch (tiling) {
214 	default:
215 	case I915_TILING_NONE:
216 		/*
217 		 * The Intel GPU doesn't need any alignment in linear mode,
218 		 * but libva requires the allocation stride to be aligned to
219 		 * 16 bytes and height to 4 rows. Further, we round up the
220 		 * horizontal alignment so that row start on a cache line (64
221 		 * bytes).
222 		 */
223 		horizontal_alignment = 64;
224 		vertical_alignment = 4;
225 		break;
226 
227 	case I915_TILING_X:
228 		horizontal_alignment = 512;
229 		vertical_alignment = 8;
230 		break;
231 
232 	case I915_TILING_Y:
233 		if (i915->gen == 3) {
234 			horizontal_alignment = 512;
235 			vertical_alignment = 8;
236 		} else {
237 			horizontal_alignment = 128;
238 			vertical_alignment = 32;
239 		}
240 		break;
241 	}
242 
243 	*aligned_height = ALIGN(bo->height, vertical_alignment);
244 	if (i915->gen > 3) {
245 		*stride = ALIGN(*stride, horizontal_alignment);
246 	} else {
247 		while (*stride > horizontal_alignment)
248 			horizontal_alignment <<= 1;
249 
250 		*stride = horizontal_alignment;
251 	}
252 
253 	if (i915->gen <= 3 && *stride > 8192)
254 		return -EINVAL;
255 
256 	return 0;
257 }
258 
i915_clflush(void * start,size_t size)259 static void i915_clflush(void *start, size_t size)
260 {
261 	void *p = (void *)(((uintptr_t)start) & ~I915_CACHELINE_MASK);
262 	void *end = (void *)((uintptr_t)start + size);
263 
264 	__builtin_ia32_mfence();
265 	while (p < end) {
266 		__builtin_ia32_clflush(p);
267 		p = (void *)((uintptr_t)p + I915_CACHELINE_SIZE);
268 	}
269 }
270 
i915_init(struct driver * drv)271 static int i915_init(struct driver *drv)
272 {
273 	int ret;
274 	int device_id;
275 	struct i915_device *i915;
276 	drm_i915_getparam_t get_param;
277 
278 	i915 = calloc(1, sizeof(*i915));
279 	if (!i915)
280 		return -ENOMEM;
281 
282 	memset(&get_param, 0, sizeof(get_param));
283 	get_param.param = I915_PARAM_CHIPSET_ID;
284 	get_param.value = &device_id;
285 	ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
286 	if (ret) {
287 		drv_log("Failed to get I915_PARAM_CHIPSET_ID\n");
288 		free(i915);
289 		return -EINVAL;
290 	}
291 
292 	i915->gen = i915_get_gen(device_id);
293 
294 	memset(&get_param, 0, sizeof(get_param));
295 	get_param.param = I915_PARAM_HAS_LLC;
296 	get_param.value = &i915->has_llc;
297 	ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
298 	if (ret) {
299 		drv_log("Failed to get I915_PARAM_HAS_LLC\n");
300 		free(i915);
301 		return -EINVAL;
302 	}
303 
304 	drv->priv = i915;
305 
306 	return i915_add_combinations(drv);
307 }
308 
i915_bo_from_format(struct bo * bo,uint32_t width,uint32_t height,uint32_t format)309 static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format)
310 {
311 	uint32_t offset;
312 	size_t plane;
313 	int ret;
314 
315 	offset = 0;
316 	for (plane = 0; plane < drv_num_planes_from_format(format); plane++) {
317 		uint32_t stride = drv_stride_from_format(format, width, plane);
318 		uint32_t plane_height = drv_height_from_format(format, height, plane);
319 
320 		if (bo->tiling != I915_TILING_NONE)
321 			assert(IS_ALIGNED(offset, 4096));
322 
323 		ret = i915_align_dimensions(bo, bo->tiling, &stride, &plane_height);
324 		if (ret)
325 			return ret;
326 
327 		bo->strides[plane] = stride;
328 		bo->sizes[plane] = stride * plane_height;
329 		bo->offsets[plane] = offset;
330 		offset += bo->sizes[plane];
331 	}
332 
333 	bo->total_size = offset;
334 
335 	return 0;
336 }
337 
i915_bo_create_for_modifier(struct bo * bo,uint32_t width,uint32_t height,uint32_t format,uint64_t modifier)338 static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height,
339 				       uint32_t format, uint64_t modifier)
340 {
341 	int ret;
342 	size_t plane;
343 	struct drm_i915_gem_create gem_create;
344 	struct drm_i915_gem_set_tiling gem_set_tiling;
345 
346 	switch (modifier) {
347 	case DRM_FORMAT_MOD_LINEAR:
348 		bo->tiling = I915_TILING_NONE;
349 		break;
350 	case I915_FORMAT_MOD_X_TILED:
351 		bo->tiling = I915_TILING_X;
352 		break;
353 	case I915_FORMAT_MOD_Y_TILED:
354 		bo->tiling = I915_TILING_Y;
355 		break;
356 	}
357 
358 	bo->format_modifiers[0] = modifier;
359 
360 	if (format == DRM_FORMAT_YVU420_ANDROID) {
361 		/*
362 		 * We only need to be able to use this as a linear texture,
363 		 * which doesn't put any HW restrictions on how we lay it
364 		 * out. The Android format does require the stride to be a
365 		 * multiple of 16 and expects the Cr and Cb stride to be
366 		 * ALIGN(Y_stride / 2, 16), which we can make happen by
367 		 * aligning to 32 bytes here.
368 		 */
369 		uint32_t stride = ALIGN(width, 32);
370 		drv_bo_from_format(bo, stride, height, format);
371 	} else {
372 		i915_bo_from_format(bo, width, height, format);
373 	}
374 
375 	memset(&gem_create, 0, sizeof(gem_create));
376 	gem_create.size = bo->total_size;
377 
378 	ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
379 	if (ret) {
380 		drv_log("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
381 		return ret;
382 	}
383 
384 	for (plane = 0; plane < bo->num_planes; plane++)
385 		bo->handles[plane].u32 = gem_create.handle;
386 
387 	memset(&gem_set_tiling, 0, sizeof(gem_set_tiling));
388 	gem_set_tiling.handle = bo->handles[0].u32;
389 	gem_set_tiling.tiling_mode = bo->tiling;
390 	gem_set_tiling.stride = bo->strides[0];
391 
392 	ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
393 	if (ret) {
394 		struct drm_gem_close gem_close;
395 		memset(&gem_close, 0, sizeof(gem_close));
396 		gem_close.handle = bo->handles[0].u32;
397 		drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
398 
399 		drv_log("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
400 		return -errno;
401 	}
402 
403 	return 0;
404 }
405 
i915_bo_create(struct bo * bo,uint32_t width,uint32_t height,uint32_t format,uint64_t use_flags)406 static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
407 			  uint64_t use_flags)
408 {
409 	struct combination *combo;
410 
411 	combo = drv_get_combination(bo->drv, format, use_flags);
412 	if (!combo)
413 		return -EINVAL;
414 
415 	return i915_bo_create_for_modifier(bo, width, height, format, combo->metadata.modifier);
416 }
417 
i915_bo_create_with_modifiers(struct bo * bo,uint32_t width,uint32_t height,uint32_t format,const uint64_t * modifiers,uint32_t count)418 static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height,
419 					 uint32_t format, const uint64_t *modifiers, uint32_t count)
420 {
421 	static const uint64_t modifier_order[] = {
422 		I915_FORMAT_MOD_Y_TILED,
423 		I915_FORMAT_MOD_X_TILED,
424 		DRM_FORMAT_MOD_LINEAR,
425 	};
426 	uint64_t modifier;
427 
428 	modifier = drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order));
429 
430 	return i915_bo_create_for_modifier(bo, width, height, format, modifier);
431 }
432 
i915_close(struct driver * drv)433 static void i915_close(struct driver *drv)
434 {
435 	free(drv->priv);
436 	drv->priv = NULL;
437 }
438 
i915_bo_import(struct bo * bo,struct drv_import_fd_data * data)439 static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
440 {
441 	int ret;
442 	struct drm_i915_gem_get_tiling gem_get_tiling;
443 
444 	ret = drv_prime_bo_import(bo, data);
445 	if (ret)
446 		return ret;
447 
448 	/* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
449 	memset(&gem_get_tiling, 0, sizeof(gem_get_tiling));
450 	gem_get_tiling.handle = bo->handles[0].u32;
451 
452 	ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
453 	if (ret) {
454 		drv_gem_bo_destroy(bo);
455 		drv_log("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
456 		return ret;
457 	}
458 
459 	bo->tiling = gem_get_tiling.tiling_mode;
460 	return 0;
461 }
462 
i915_bo_map(struct bo * bo,struct vma * vma,size_t plane,uint32_t map_flags)463 static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
464 {
465 	int ret;
466 	void *addr;
467 
468 	if (bo->tiling == I915_TILING_NONE) {
469 		struct drm_i915_gem_mmap gem_map;
470 		memset(&gem_map, 0, sizeof(gem_map));
471 
472 		if ((bo->use_flags & BO_USE_SCANOUT) && !(bo->use_flags & BO_USE_RENDERSCRIPT))
473 			gem_map.flags = I915_MMAP_WC;
474 
475 		gem_map.handle = bo->handles[0].u32;
476 		gem_map.offset = 0;
477 		gem_map.size = bo->total_size;
478 
479 		ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
480 		if (ret) {
481 			drv_log("DRM_IOCTL_I915_GEM_MMAP failed\n");
482 			return MAP_FAILED;
483 		}
484 
485 		addr = (void *)(uintptr_t)gem_map.addr_ptr;
486 	} else {
487 		struct drm_i915_gem_mmap_gtt gem_map;
488 		memset(&gem_map, 0, sizeof(gem_map));
489 
490 		gem_map.handle = bo->handles[0].u32;
491 
492 		ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map);
493 		if (ret) {
494 			drv_log("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
495 			return MAP_FAILED;
496 		}
497 
498 		addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd,
499 			    gem_map.offset);
500 	}
501 
502 	if (addr == MAP_FAILED) {
503 		drv_log("i915 GEM mmap failed\n");
504 		return addr;
505 	}
506 
507 	vma->length = bo->total_size;
508 	return addr;
509 }
510 
i915_bo_invalidate(struct bo * bo,struct mapping * mapping)511 static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping)
512 {
513 	int ret;
514 	struct drm_i915_gem_set_domain set_domain;
515 
516 	memset(&set_domain, 0, sizeof(set_domain));
517 	set_domain.handle = bo->handles[0].u32;
518 	if (bo->tiling == I915_TILING_NONE) {
519 		set_domain.read_domains = I915_GEM_DOMAIN_CPU;
520 		if (mapping->vma->map_flags & BO_MAP_WRITE)
521 			set_domain.write_domain = I915_GEM_DOMAIN_CPU;
522 	} else {
523 		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
524 		if (mapping->vma->map_flags & BO_MAP_WRITE)
525 			set_domain.write_domain = I915_GEM_DOMAIN_GTT;
526 	}
527 
528 	ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
529 	if (ret) {
530 		drv_log("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
531 		return ret;
532 	}
533 
534 	return 0;
535 }
536 
i915_bo_flush(struct bo * bo,struct mapping * mapping)537 static int i915_bo_flush(struct bo *bo, struct mapping *mapping)
538 {
539 	struct i915_device *i915 = bo->drv->priv;
540 	if (!i915->has_llc && bo->tiling == I915_TILING_NONE)
541 		i915_clflush(mapping->vma->addr, mapping->vma->length);
542 
543 	return 0;
544 }
545 
i915_resolve_format(uint32_t format,uint64_t use_flags)546 static uint32_t i915_resolve_format(uint32_t format, uint64_t use_flags)
547 {
548 	switch (format) {
549 	case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
550 		/* KBL camera subsystem requires NV12. */
551 		if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE))
552 			return DRM_FORMAT_NV12;
553 		/*HACK: See b/28671744 */
554 		return DRM_FORMAT_XBGR8888;
555 	case DRM_FORMAT_FLEX_YCbCr_420_888:
556 		/*
557 		 * KBL camera subsystem requires NV12. Our other use cases
558 		 * don't care:
559 		 * - Hardware video supports NV12,
560 		 * - USB Camera HALv3 supports NV12,
561 		 * - USB Camera HALv1 doesn't use this format.
562 		 * Moreover, NV12 is preferred for video, due to overlay
563 		 * support on SKL+.
564 		 */
565 		return DRM_FORMAT_NV12;
566 	default:
567 		return format;
568 	}
569 }
570 
571 const struct backend backend_i915 = {
572 	.name = "i915",
573 	.init = i915_init,
574 	.close = i915_close,
575 	.bo_create = i915_bo_create,
576 	.bo_create_with_modifiers = i915_bo_create_with_modifiers,
577 	.bo_destroy = drv_gem_bo_destroy,
578 	.bo_import = i915_bo_import,
579 	.bo_map = i915_bo_map,
580 	.bo_unmap = drv_bo_munmap,
581 	.bo_invalidate = i915_bo_invalidate,
582 	.bo_flush = i915_bo_flush,
583 	.resolve_format = i915_resolve_format,
584 };
585 
586 #endif
587