2 * Copyright (c) 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.
20 struct gbm_i915_device
26 static int get_gen(int device_id)
28 const uint16_t gen3_ids[] = {0x2582, 0x2592, 0x2772, 0x27A2, 0x27AE, 0x29C2, 0x29B2, 0x29D2, 0xA001, 0xA011};
30 for(i = 0; i < ARRAY_SIZE(gen3_ids); i++)
31 if (gen3_ids[i] == device_id)
37 int gbm_i915_init(struct gbm_device *gbm)
39 struct gbm_i915_device *i915_gbm;
40 drm_i915_getparam_t get_param;
44 i915_gbm = (struct gbm_i915_device*)malloc(sizeof(*i915_gbm));
48 memset(&get_param, 0, sizeof(get_param));
49 get_param.param = I915_PARAM_CHIPSET_ID;
50 get_param.value = &device_id;
51 ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GETPARAM, &get_param);
53 fprintf(stderr, "minigbm: DRM_IOCTL_I915_GETPARAM failed\n");
58 i915_gbm->gen = get_gen(device_id);
65 void gbm_i915_close(struct gbm_device *gbm)
71 static void i915_align_dimensions(struct gbm_device *gbm, uint32_t tiling_mode, uint32_t *width, uint32_t *height, int bpp)
73 struct gbm_i915_device *i915_gbm = (struct gbm_i915_device *)gbm->priv;
74 uint32_t width_alignment = 4, height_alignment = 4;
78 case I915_TILING_NONE:
79 width_alignment = 64 / bpp;
83 width_alignment = 512 / bpp;
88 if (i915_gbm->gen == 3) {
89 width_alignment = 512 / bpp;
92 width_alignment = 128 / bpp;
93 height_alignment = 32;
98 if (i915_gbm->gen > 3) {
99 *width = ALIGN(*width, width_alignment);
100 *height = ALIGN(*height, height_alignment);
103 for (w = width_alignment; w < *width; w <<= 1)
106 *height = ALIGN(*height, height_alignment);
110 static int i915_verify_dimensions(struct gbm_device *gbm, uint32_t stride, uint32_t height)
112 struct gbm_i915_device *i915_gbm = (struct gbm_i915_device *)gbm->priv;
113 if (i915_gbm->gen <= 3 && stride > 8192)
119 int gbm_i915_bo_create(struct gbm_bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
121 struct gbm_device *gbm = bo->gbm;
122 int bpp = gbm_bytes_from_format(format);
123 struct drm_i915_gem_create gem_create;
124 struct drm_i915_gem_set_tiling gem_set_tiling;
125 uint32_t tiling_mode = I915_TILING_NONE;
129 if (flags & GBM_BO_USE_CURSOR)
130 tiling_mode = I915_TILING_NONE;
131 else if (flags & GBM_BO_USE_SCANOUT)
132 tiling_mode = I915_TILING_X;
133 else if (flags & GBM_BO_USE_RENDERING)
134 tiling_mode = I915_TILING_Y;
136 i915_align_dimensions(gbm, tiling_mode, &width, &height, bpp);
138 bo->stride = width * bpp;
140 if (!i915_verify_dimensions(gbm, bo->stride, height))
143 memset(&gem_create, 0, sizeof(gem_create));
144 size = width * height * bpp;
145 gem_create.size = size;
147 ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
149 fprintf(stderr, "minigbm: DRM_IOCTL_I915_GEM_CREATE failed "
150 "(size=%zu)\n", size);
153 bo->handle.u32 = gem_create.handle;
156 memset(&gem_set_tiling, 0, sizeof(gem_set_tiling));
158 gem_set_tiling.handle = bo->handle.u32;
159 gem_set_tiling.tiling_mode = tiling_mode;
160 gem_set_tiling.stride = bo->stride;
161 ret = drmIoctl(gbm->fd, DRM_IOCTL_I915_GEM_SET_TILING, &gem_set_tiling);
162 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
165 struct drm_gem_close gem_close;
166 gem_close.handle = bo->handle.u32;
167 fprintf(stderr, "minigbm: DRM_IOCTL_I915_GEM_SET_TILING failed "
168 "errno=%x (handle=%x, tiling=%x, stride=%x)\n",
170 gem_set_tiling.handle,
171 gem_set_tiling.tiling_mode,
172 gem_set_tiling.stride);
173 drmIoctl(gbm->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
180 const struct gbm_driver gbm_driver_i915 =
183 .init = gbm_i915_init,
184 .close = gbm_i915_close,
185 .bo_create = gbm_i915_bo_create,
186 .bo_destroy = gbm_gem_bo_destroy,
188 {GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
189 {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
190 {GBM_FORMAT_XBGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
191 {GBM_FORMAT_ABGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
192 {GBM_FORMAT_XRGB1555, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
193 {GBM_FORMAT_ARGB1555, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},
194 {GBM_FORMAT_RGB565, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING | GBM_BO_USE_WRITE},