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.
23 #define I915_CACHELINE_SIZE 64
24 #define I915_CACHELINE_MASK (I915_CACHELINE_SIZE - 1)
26 static const uint32_t render_target_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555,
27 DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565,
28 DRM_FORMAT_XBGR2101010, DRM_FORMAT_XBGR8888,
29 DRM_FORMAT_XRGB1555, DRM_FORMAT_XRGB2101010,
30 DRM_FORMAT_XRGB8888 };
32 static const uint32_t tileable_texture_source_formats[] = { DRM_FORMAT_GR88, DRM_FORMAT_R8,
33 DRM_FORMAT_UYVY, DRM_FORMAT_YUYV };
35 static const uint32_t texture_source_formats[] = { DRM_FORMAT_YVU420, DRM_FORMAT_YVU420_ANDROID,
43 static uint32_t i915_get_gen(int device_id)
45 const uint16_t gen3_ids[] = { 0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE,
46 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011 };
48 for (i = 0; i < ARRAY_SIZE(gen3_ids); i++)
49 if (gen3_ids[i] == device_id)
56 * We allow allocation of ARGB formats for SCANOUT if the corresponding XRGB
57 * formats supports it. It's up to the caller (chrome ozone) to ultimately not
58 * scan out ARGB if the display controller only supports XRGB, but we'll allow
59 * the allocation of the bo here.
61 static bool format_compatible(const struct combination *combo, uint32_t format)
63 if (combo->format == format)
67 case DRM_FORMAT_XRGB8888:
68 return combo->format == DRM_FORMAT_ARGB8888;
69 case DRM_FORMAT_XBGR8888:
70 return combo->format == DRM_FORMAT_ABGR8888;
71 case DRM_FORMAT_RGBX8888:
72 return combo->format == DRM_FORMAT_RGBA8888;
73 case DRM_FORMAT_BGRX8888:
74 return combo->format == DRM_FORMAT_BGRA8888;
80 static int i915_add_kms_item(struct driver *drv, const struct kms_item *item)
83 struct combination *combo;
86 * Older hardware can't scanout Y-tiled formats. Newer devices can, and
87 * report this functionality via format modifiers.
89 for (i = 0; i < drv_array_size(drv->combos); i++) {
90 combo = (struct combination *)drv_array_at_idx(drv->combos, i);
91 if (!format_compatible(combo, item->format))
94 if (item->modifier == DRM_FORMAT_MOD_LINEAR &&
95 combo->metadata.tiling == I915_TILING_X) {
97 * FIXME: drv_query_kms() does not report the available modifiers
98 * yet, but we know that all hardware can scanout from X-tiled
99 * buffers, so let's add this to our combinations, except for
100 * cursor, which must not be tiled.
102 combo->use_flags |= item->use_flags & ~BO_USE_CURSOR;
105 /* If we can scanout NV12, we support all tiling modes. */
106 if (item->format == DRM_FORMAT_NV12)
107 combo->use_flags |= item->use_flags;
109 if (combo->metadata.modifier == item->modifier)
110 combo->use_flags |= item->use_flags;
116 static int i915_add_combinations(struct driver *drv)
120 struct drv_array *kms_items;
121 struct format_metadata metadata;
122 uint64_t render_use_flags, texture_use_flags;
124 render_use_flags = BO_USE_RENDER_MASK;
125 texture_use_flags = BO_USE_TEXTURE_MASK;
127 metadata.tiling = I915_TILING_NONE;
128 metadata.priority = 1;
129 metadata.modifier = DRM_FORMAT_MOD_LINEAR;
131 drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
132 &metadata, render_use_flags);
134 drv_add_combinations(drv, texture_source_formats, ARRAY_SIZE(texture_source_formats),
135 &metadata, texture_use_flags);
137 drv_add_combinations(drv, tileable_texture_source_formats,
138 ARRAY_SIZE(tileable_texture_source_formats), &metadata,
141 /* Android CTS tests require this. */
142 drv_add_combination(drv, DRM_FORMAT_BGR888, &metadata, BO_USE_SW_MASK);
144 drv_modify_combination(drv, DRM_FORMAT_XRGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT);
145 drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &metadata, BO_USE_CURSOR | BO_USE_SCANOUT);
147 /* IPU3 camera ISP supports only NV12 output. */
148 drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
149 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
151 * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
154 drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
155 BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
157 render_use_flags &= ~BO_USE_RENDERSCRIPT;
158 render_use_flags &= ~BO_USE_SW_WRITE_OFTEN;
159 render_use_flags &= ~BO_USE_SW_READ_OFTEN;
160 render_use_flags &= ~BO_USE_LINEAR;
161 render_use_flags &= ~BO_USE_PROTECTED;
163 texture_use_flags &= ~BO_USE_RENDERSCRIPT;
164 texture_use_flags &= ~BO_USE_SW_WRITE_OFTEN;
165 texture_use_flags &= ~BO_USE_SW_READ_OFTEN;
166 texture_use_flags &= ~BO_USE_LINEAR;
167 texture_use_flags &= ~BO_USE_PROTECTED;
169 metadata.tiling = I915_TILING_X;
170 metadata.priority = 2;
171 metadata.modifier = I915_FORMAT_MOD_X_TILED;
173 drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
174 &metadata, render_use_flags);
176 drv_add_combinations(drv, tileable_texture_source_formats,
177 ARRAY_SIZE(tileable_texture_source_formats), &metadata,
180 metadata.tiling = I915_TILING_Y;
181 metadata.priority = 3;
182 metadata.modifier = I915_FORMAT_MOD_Y_TILED;
184 drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
185 &metadata, render_use_flags);
187 drv_add_combinations(drv, tileable_texture_source_formats,
188 ARRAY_SIZE(tileable_texture_source_formats), &metadata,
191 /* Support y-tiled NV12 for libva */
192 drv_add_combination(drv, DRM_FORMAT_NV12, &metadata,
193 BO_USE_TEXTURE | BO_USE_HW_VIDEO_DECODER);
195 kms_items = drv_query_kms(drv);
199 for (i = 0; i < drv_array_size(kms_items); i++) {
200 ret = i915_add_kms_item(drv, (struct kms_item *)drv_array_at_idx(kms_items, i));
202 drv_array_destroy(kms_items);
207 drv_array_destroy(kms_items);
211 static int i915_align_dimensions(struct bo *bo, uint32_t tiling, uint32_t *stride,
212 uint32_t *aligned_height)
214 struct i915_device *i915 = bo->drv->priv;
215 uint32_t horizontal_alignment;
216 uint32_t vertical_alignment;
220 case I915_TILING_NONE:
222 * The Intel GPU doesn't need any alignment in linear mode,
223 * but libva requires the allocation stride to be aligned to
224 * 16 bytes and height to 4 rows. Further, we round up the
225 * horizontal alignment so that row start on a cache line (64
228 horizontal_alignment = 64;
229 vertical_alignment = 4;
233 horizontal_alignment = 512;
234 vertical_alignment = 8;
238 if (i915->gen == 3) {
239 horizontal_alignment = 512;
240 vertical_alignment = 8;
242 horizontal_alignment = 128;
243 vertical_alignment = 32;
248 *aligned_height = ALIGN(bo->height, vertical_alignment);
250 *stride = ALIGN(*stride, horizontal_alignment);
252 while (*stride > horizontal_alignment)
253 horizontal_alignment <<= 1;
255 *stride = horizontal_alignment;
258 if (i915->gen <= 3 && *stride > 8192)
264 static void i915_clflush(void *start, size_t size)
266 void *p = (void *)(((uintptr_t)start) & ~I915_CACHELINE_MASK);
267 void *end = (void *)((uintptr_t)start + size);
269 __builtin_ia32_mfence();
271 __builtin_ia32_clflush(p);
272 p = (void *)((uintptr_t)p + I915_CACHELINE_SIZE);
276 static int i915_init(struct driver *drv)
280 struct i915_device *i915;
281 drm_i915_getparam_t get_param;
283 i915 = calloc(1, sizeof(*i915));
287 memset(&get_param, 0, sizeof(get_param));
288 get_param.param = I915_PARAM_CHIPSET_ID;
289 get_param.value = &device_id;
290 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
292 drv_log("Failed to get I915_PARAM_CHIPSET_ID\n");
297 i915->gen = i915_get_gen(device_id);
299 memset(&get_param, 0, sizeof(get_param));
300 get_param.param = I915_PARAM_HAS_LLC;
301 get_param.value = &i915->has_llc;
302 ret = drmIoctl(drv->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
304 drv_log("Failed to get I915_PARAM_HAS_LLC\n");
311 return i915_add_combinations(drv);
314 static int i915_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format)
321 pagesize = getpagesize();
322 for (plane = 0; plane < drv_num_planes_from_format(format); plane++) {
323 uint32_t stride = drv_stride_from_format(format, width, plane);
324 uint32_t plane_height = drv_height_from_format(format, height, plane);
326 if (bo->tiling != I915_TILING_NONE)
327 assert(IS_ALIGNED(offset, pagesize));
329 ret = i915_align_dimensions(bo, bo->tiling, &stride, &plane_height);
333 bo->strides[plane] = stride;
334 bo->sizes[plane] = stride * plane_height;
335 bo->offsets[plane] = offset;
336 offset += bo->sizes[plane];
339 bo->total_size = ALIGN(offset, pagesize);
344 static int i915_bo_create_for_modifier(struct bo *bo, uint32_t width, uint32_t height,
345 uint32_t format, uint64_t modifier)
349 struct drm_i915_gem_create gem_create;
350 struct drm_i915_gem_set_tiling gem_set_tiling;
353 case DRM_FORMAT_MOD_LINEAR:
354 bo->tiling = I915_TILING_NONE;
356 case I915_FORMAT_MOD_X_TILED:
357 bo->tiling = I915_TILING_X;
359 case I915_FORMAT_MOD_Y_TILED:
360 bo->tiling = I915_TILING_Y;
364 bo->format_modifiers[0] = modifier;
366 if (format == DRM_FORMAT_YVU420_ANDROID) {
368 * We only need to be able to use this as a linear texture,
369 * which doesn't put any HW restrictions on how we lay it
370 * out. The Android format does require the stride to be a
371 * multiple of 16 and expects the Cr and Cb stride to be
372 * ALIGN(Y_stride / 2, 16), which we can make happen by
373 * aligning to 32 bytes here.
375 uint32_t stride = ALIGN(width, 32);
376 drv_bo_from_format(bo, stride, height, format);
378 i915_bo_from_format(bo, width, height, format);
381 memset(&gem_create, 0, sizeof(gem_create));
382 gem_create.size = bo->total_size;
384 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
386 drv_log("DRM_IOCTL_I915_GEM_CREATE failed (size=%llu)\n", gem_create.size);
390 for (plane = 0; plane < bo->num_planes; plane++)
391 bo->handles[plane].u32 = gem_create.handle;
393 memset(&gem_set_tiling, 0, sizeof(gem_set_tiling));
394 gem_set_tiling.handle = bo->handles[0].u32;
395 gem_set_tiling.tiling_mode = bo->tiling;
396 gem_set_tiling.stride = bo->strides[0];
398 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
400 struct drm_gem_close gem_close;
401 memset(&gem_close, 0, sizeof(gem_close));
402 gem_close.handle = bo->handles[0].u32;
403 drmIoctl(bo->drv->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
405 drv_log("DRM_IOCTL_I915_GEM_SET_TILING failed with %d\n", errno);
412 static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
415 struct combination *combo;
417 combo = drv_get_combination(bo->drv, format, use_flags);
421 return i915_bo_create_for_modifier(bo, width, height, format, combo->metadata.modifier);
424 static int i915_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height,
425 uint32_t format, const uint64_t *modifiers, uint32_t count)
427 static const uint64_t modifier_order[] = {
428 I915_FORMAT_MOD_Y_TILED,
429 I915_FORMAT_MOD_X_TILED,
430 DRM_FORMAT_MOD_LINEAR,
434 modifier = drv_pick_modifier(modifiers, count, modifier_order, ARRAY_SIZE(modifier_order));
436 return i915_bo_create_for_modifier(bo, width, height, format, modifier);
439 static void i915_close(struct driver *drv)
445 static int i915_bo_import(struct bo *bo, struct drv_import_fd_data *data)
448 struct drm_i915_gem_get_tiling gem_get_tiling;
450 ret = drv_prime_bo_import(bo, data);
454 /* TODO(gsingh): export modifiers and get rid of backdoor tiling. */
455 memset(&gem_get_tiling, 0, sizeof(gem_get_tiling));
456 gem_get_tiling.handle = bo->handles[0].u32;
458 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_GET_TILING, &gem_get_tiling);
460 drv_gem_bo_destroy(bo);
461 drv_log("DRM_IOCTL_I915_GEM_GET_TILING failed.\n");
465 bo->tiling = gem_get_tiling.tiling_mode;
469 static void *i915_bo_map(struct bo *bo, struct vma *vma, size_t plane, uint32_t map_flags)
474 if (bo->tiling == I915_TILING_NONE) {
475 struct drm_i915_gem_mmap gem_map;
476 memset(&gem_map, 0, sizeof(gem_map));
478 /* TODO(b/118799155): We don't seem to have a good way to
479 * detect the use cases for which WC mapping is really needed.
480 * The current heuristic seems overly coarse and may be slowing
481 * down some other use cases unnecessarily.
483 * For now, care must be taken not to use WC mappings for
484 * Renderscript and camera use cases, as they're
485 * performance-sensitive. */
486 if ((bo->use_flags & BO_USE_SCANOUT) &&
488 (BO_USE_RENDERSCRIPT | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE)))
489 gem_map.flags = I915_MMAP_WC;
491 gem_map.handle = bo->handles[0].u32;
493 gem_map.size = bo->total_size;
495 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_map);
497 drv_log("DRM_IOCTL_I915_GEM_MMAP failed\n");
501 addr = (void *)(uintptr_t)gem_map.addr_ptr;
503 struct drm_i915_gem_mmap_gtt gem_map;
504 memset(&gem_map, 0, sizeof(gem_map));
506 gem_map.handle = bo->handles[0].u32;
508 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &gem_map);
510 drv_log("DRM_IOCTL_I915_GEM_MMAP_GTT failed\n");
514 addr = mmap(0, bo->total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd,
518 if (addr == MAP_FAILED) {
519 drv_log("i915 GEM mmap failed\n");
523 vma->length = bo->total_size;
527 static int i915_bo_invalidate(struct bo *bo, struct mapping *mapping)
530 struct drm_i915_gem_set_domain set_domain;
532 memset(&set_domain, 0, sizeof(set_domain));
533 set_domain.handle = bo->handles[0].u32;
534 if (bo->tiling == I915_TILING_NONE) {
535 set_domain.read_domains = I915_GEM_DOMAIN_CPU;
536 if (mapping->vma->map_flags & BO_MAP_WRITE)
537 set_domain.write_domain = I915_GEM_DOMAIN_CPU;
539 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
540 if (mapping->vma->map_flags & BO_MAP_WRITE)
541 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
544 ret = drmIoctl(bo->drv->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
546 drv_log("DRM_IOCTL_I915_GEM_SET_DOMAIN with %d\n", ret);
553 static int i915_bo_flush(struct bo *bo, struct mapping *mapping)
555 struct i915_device *i915 = bo->drv->priv;
556 if (!i915->has_llc && bo->tiling == I915_TILING_NONE)
557 i915_clflush(mapping->vma->addr, mapping->vma->length);
562 static uint32_t i915_resolve_format(uint32_t format, uint64_t use_flags)
565 case DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED:
566 /* KBL camera subsystem requires NV12. */
567 if (use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE))
568 return DRM_FORMAT_NV12;
569 /*HACK: See b/28671744 */
570 return DRM_FORMAT_XBGR8888;
571 case DRM_FORMAT_FLEX_YCbCr_420_888:
573 * KBL camera subsystem requires NV12. Our other use cases
575 * - Hardware video supports NV12,
576 * - USB Camera HALv3 supports NV12,
577 * - USB Camera HALv1 doesn't use this format.
578 * Moreover, NV12 is preferred for video, due to overlay
581 return DRM_FORMAT_NV12;
587 const struct backend backend_i915 = {
591 .bo_create = i915_bo_create,
592 .bo_create_with_modifiers = i915_bo_create_with_modifiers,
593 .bo_destroy = drv_gem_bo_destroy,
594 .bo_import = i915_bo_import,
595 .bo_map = i915_bo_map,
596 .bo_unmap = drv_bo_munmap,
597 .bo_invalidate = i915_bo_invalidate,
598 .bo_flush = i915_bo_flush,
599 .resolve_format = i915_resolve_format,