OSDN Git Service

Fix insignificant warnings
[android-x86/external-drm_gralloc.git] / gralloc_drm_intel.c
1 /*
2  * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
3  * Copyright (C) 2010-2011 LunarG Inc.
4  *
5  * drm_gem_intel_copy is based on xorg-driver-intel, which has
6  *
7  * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
8  * All Rights Reserved.
9  * Copyright (c) 2005 Jesse Barnes <jbarnes@virtuousgeek.org>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  */
29
30 #define LOG_TAG "GRALLOC-I915"
31
32 #include <cutils/log.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <assert.h>
36 #include <drm.h>
37 #include <intel_bufmgr.h>
38 #include <i915_drm.h>
39
40 #include "gralloc_drm.h"
41 #include "gralloc_drm_priv.h"
42
43 #define MI_NOOP                     (0)
44 #define MI_BATCH_BUFFER_END         (0x0a << 23)
45 #define MI_FLUSH                    (0x04 << 23)
46 #define MI_FLUSH_DW                 (0x26 << 23)
47 #define MI_WRITE_DIRTY_STATE        (1 << 4) 
48 #define MI_INVALIDATE_MAP_CACHE     (1 << 0)
49 #define XY_SRC_COPY_BLT_CMD         ((2 << 29) | (0x53 << 22))
50 #define XY_SRC_COPY_BLT_WRITE_ALPHA (1 << 21)
51 #define XY_SRC_COPY_BLT_WRITE_RGB   (1 << 20)
52 #define XY_SRC_COPY_BLT_SRC_TILED   (1 << 15)
53 #define XY_SRC_COPY_BLT_DST_TILED   (1 << 11)
54
55 #define DEBUG_BLT 0
56
57 struct intel_info {
58         struct gralloc_drm_drv_t base;
59
60         int fd;
61         drm_intel_bufmgr *bufmgr;
62         int gen;
63
64         drm_intel_bo *batch_ibo;
65         uint32_t *batch, *cur;
66         int capacity, size;
67         int exec_blt;
68 };
69
70 struct intel_buffer {
71         struct gralloc_drm_bo_t base;
72         drm_intel_bo *ibo;
73         uint32_t tiling;
74 };
75
76 static int
77 batch_next(struct intel_info *info)
78 {
79         info->cur = info->batch;
80
81         if (info->batch_ibo)
82                 drm_intel_bo_unreference(info->batch_ibo);
83
84         info->batch_ibo = drm_intel_bo_alloc(info->bufmgr,
85                         "gralloc-batchbuffer", info->size, 4096);
86
87         return (info->batch_ibo) ? 0 : -ENOMEM;
88 }
89
90 static int
91 batch_count(struct intel_info *info)
92 {
93         return info->cur - info->batch;
94 }
95
96 static void
97 batch_dword(struct intel_info *info, uint32_t dword)
98 {
99         *info->cur++ = dword;
100 }
101
102 static int
103 batch_reloc(struct intel_info *info, struct gralloc_drm_bo_t *bo,
104                 uint32_t read_domains, uint32_t write_domain)
105 {
106         struct intel_buffer *target = (struct intel_buffer *) bo;
107         uint32_t offset = (info->cur - info->batch) * sizeof(info->batch[0]);
108         int ret;
109
110         ret = drm_intel_bo_emit_reloc(info->batch_ibo, offset,
111                         target->ibo, 0, read_domains, write_domain);
112         if (!ret)
113                 batch_dword(info, target->ibo->offset);
114
115         return ret;
116 }
117
118 static int
119 batch_reloc64(struct intel_info *info, struct gralloc_drm_bo_t *bo,
120                 uint32_t read_domains, uint32_t write_domain)
121 {
122         struct intel_buffer *target = (struct intel_buffer *) bo;
123         uint32_t offset = (info->cur - info->batch) * sizeof(info->batch[0]);
124         int ret;
125
126         ret = drm_intel_bo_emit_reloc(info->batch_ibo, offset,
127                         target->ibo, 0, read_domains, write_domain);
128         if (!ret) {
129                 batch_dword(info, target->ibo->offset64);
130                 batch_dword(info, target->ibo->offset64 >> 32);
131         }
132
133         return ret;
134 }
135
136 static int
137 batch_flush(struct intel_info *info)
138 {
139         int size, ret;
140
141         batch_dword(info, MI_BATCH_BUFFER_END);
142         size = batch_count(info);
143         if (size & 1) {
144                 batch_dword(info, MI_NOOP);
145                 size = batch_count(info);
146         }
147
148         size *= sizeof(info->batch[0]);
149         ret = drm_intel_bo_subdata(info->batch_ibo, 0, size, info->batch);
150         if (ret) {
151                 ALOGE("failed to subdata batch");
152                 goto fail;
153         }
154         ret = drm_intel_bo_mrb_exec(info->batch_ibo, size,
155                 NULL, 0, 0, info->exec_blt);
156         if (ret) {
157                 ALOGE("failed to exec batch");
158                 goto fail;
159         }
160
161         return batch_next(info);
162
163 fail:
164         info->cur = info->batch;
165
166         return ret;
167 }
168
169 static int
170 batch_reserve(struct intel_info *info, int count)
171 {
172         int ret = 0;
173
174         if (batch_count(info) + count > info->capacity)
175                 ret = batch_flush(info);
176
177         return ret;
178 }
179
180 static void
181 batch_destroy(struct intel_info *info)
182 {
183         if (info->batch_ibo) {
184                 drm_intel_bo_unreference(info->batch_ibo);
185                 info->batch_ibo = NULL;
186         }
187
188         if (info->batch) {
189                 free(info->batch);
190                 info->batch = NULL;
191         }
192 }
193
194 static int
195 batch_init(struct intel_info *info)
196 {
197         int ret;
198
199         info->capacity = 512;
200         info->size = (info->capacity + 16) * sizeof(info->batch[0]);
201
202         info->batch = malloc(info->size);
203         if (!info->batch)
204                 return -ENOMEM;
205
206         ret = batch_next(info);
207         if (ret) {
208                 free(info->batch);
209                 info->batch = NULL;
210         }
211
212         return ret;
213 }
214
215 static void intel_resolve_format(struct gralloc_drm_drv_t *drv,
216                 struct gralloc_drm_bo_t *bo,
217                 uint32_t *pitches, uint32_t *offsets, uint32_t *handles)
218 {
219         /*
220          * TODO - should take account hw specific padding, alignment
221          * for camera, video decoder etc.
222          */
223
224         struct intel_buffer *ib = (struct intel_buffer *) bo;
225
226         memset(pitches, 0, 4 * sizeof(uint32_t));
227         memset(offsets, 0, 4 * sizeof(uint32_t));
228         memset(handles, 0, 4 * sizeof(uint32_t));
229
230         pitches[0] = ib->base.handle->stride;
231         handles[0] = ib->base.fb_handle;
232
233         switch(ib->base.handle->format) {
234                 case HAL_PIXEL_FORMAT_YV12:
235
236                         // U and V stride are half of Y plane
237                         pitches[2] = pitches[0]/2;
238                         pitches[1] = pitches[0]/2;
239
240                         // like I420 but U and V are in reverse order
241                         offsets[2] = offsets[0] +
242                                 pitches[0] * ib->base.handle->height;
243                         offsets[1] = offsets[2] +
244                                 pitches[2] * ib->base.handle->height/2;
245
246                         handles[1] = handles[2] = handles[0];
247                         break;
248
249                 case HAL_PIXEL_FORMAT_DRM_NV12:
250
251                         // U and V are interleaved in 2nd plane
252                         pitches[1] = pitches[0];
253                         offsets[1] = offsets[0] +
254                                 pitches[0] * ib->base.handle->height;
255
256                         handles[1] = handles[0];
257                         break;
258         }
259 }
260
261
262 static void intel_blit(struct gralloc_drm_drv_t *drv,
263                 struct gralloc_drm_bo_t *dst,
264                 struct gralloc_drm_bo_t *src,
265                 uint16_t dst_x1, uint16_t dst_y1,
266                 uint16_t dst_x2, uint16_t dst_y2,
267                 uint16_t src_x1, uint16_t src_y1,
268                 uint16_t src_x2, uint16_t src_y2)
269 {
270         struct intel_info *info = (struct intel_info *) drv;
271         struct intel_buffer *dst_ib = (struct intel_buffer *) dst;
272         struct intel_buffer *src_ib = (struct intel_buffer *) src;
273         drm_intel_bo *bo_table[3];
274         uint32_t cmd, br13, dst_pitch, src_pitch;
275
276         /*
277          * XY_SRC_COPY_BLT_CMD does not support scaling,
278          * rectangle dimensions much match
279          */
280         if (src_x2 - src_x1 != dst_x2 - dst_x1 ||
281                 src_y2 - src_y1 != dst_y2 - dst_y1) {
282                 ALOGE("%s, src and dst rect must match", __func__);
283                 return;
284         }
285
286         if (dst->handle->format != src->handle->format) {
287                 ALOGE("%s, src and dst format must match", __func__);
288                 return;
289         }
290
291         /* nothing to blit */
292         if (src_x2 <= src_x1 || src_y2 <= src_y1)
293                 return;
294
295         /* clamp x2, y2 to surface size */
296         if (src_x2 > src->handle->width)
297                 src_x2 = src->handle->width;
298         if (src_y2 > src->handle->height)
299                 src_y2 = src->handle->height;
300
301         if (dst_x2 > dst->handle->width)
302                 dst_x2 = dst->handle->width;
303         if (dst_y2 > dst->handle->height)
304                 dst_y2 = dst->handle->height;
305
306         bo_table[0] = info->batch_ibo;
307         bo_table[1] = src_ib->ibo;
308         bo_table[2] = dst_ib->ibo;
309         if (drm_intel_bufmgr_check_aperture_space(bo_table, 3)) {
310                 if (batch_flush(info))
311                         return;
312                 assert(!drm_intel_bufmgr_check_aperture_space(bo_table, 3));
313         }
314
315         cmd = XY_SRC_COPY_BLT_CMD;
316         br13 = 0xcc << 16; /* ROP_S/GXcopy */
317         dst_pitch = dst->handle->stride;
318         src_pitch = src->handle->stride;
319
320         /* Blit pitch must be dword-aligned.  Otherwise, the hardware appears to
321          * drop the low bits.
322          */
323         if (src_pitch % 4 != 0 || dst_pitch % 4 != 0) {
324                 ALOGE("%s, src and dst pitch must be dword aligned", __func__);
325                 return;
326         }
327
328         switch (gralloc_drm_get_bpp(dst->handle->format)) {
329         case 1:
330                 break;
331         case 2:
332                 br13 |= (1 << 24);
333                 break;
334         case 4:
335                 br13 |= (1 << 24) | (1 << 25);
336                 cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
337                 break;
338         default:
339                 ALOGE("%s, copy with unsupported format", __func__);
340                 return;
341         }
342
343         if (info->gen >= 40) {
344                 if (dst_ib->tiling != I915_TILING_NONE) {
345                         assert(dst_pitch % 512 == 0);
346                         dst_pitch >>= 2;
347                         cmd |= XY_SRC_COPY_BLT_DST_TILED;
348                 }
349                 if (src_ib->tiling != I915_TILING_NONE) {
350                         assert(src_pitch % 512 == 0);
351                         src_pitch >>= 2;
352                         cmd |= XY_SRC_COPY_BLT_SRC_TILED;
353                 }
354         }
355
356         unsigned length = (info->gen >= 80) ? 10 : 8;
357         if (batch_reserve(info, length))
358                 return;
359
360         ALOGD_IF(DEBUG_BLT, "running batch commands, gen=%d tiling: [%d, %d]. dst=[%d, %d, %d, %d], "
361                         "src=[%d, %d, %d, %d], pitch=[%d, %d]",
362                         info->gen, dst_ib->tiling, src_ib->tiling,
363                         dst_x1, dst_y1, dst_x2, dst_y2,
364                         src_x1, src_y1, src_x2, src_y2,
365                         dst_pitch, src_pitch);
366
367         batch_dword(info, cmd | (length - 2));
368         batch_dword(info, br13 | (uint16_t)dst_pitch);
369         batch_dword(info, (dst_y1 << 16) | dst_x1);
370         batch_dword(info, (dst_y2 << 16) | dst_x2);
371         if (info->gen >= 80) {
372                 batch_reloc64(info, dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
373         } else {
374                 batch_reloc(info, dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
375         }
376         batch_dword(info, (src_y1 << 16) | src_x1);
377         batch_dword(info, (uint16_t)src_pitch);
378         if (info->gen >= 80) {
379                 batch_reloc64(info, src, I915_GEM_DOMAIN_RENDER, 0);
380         } else {
381                 batch_reloc(info, src, I915_GEM_DOMAIN_RENDER, 0);
382         }
383
384         if (info->gen >= 60) {
385                 batch_reserve(info, 4);
386                 batch_dword(info, MI_FLUSH_DW | 2);
387                 batch_dword(info, 0);
388                 batch_dword(info, 0);
389                 batch_dword(info, 0);
390         }
391         else {
392                 int flags = (info->gen >= 40) ? 0 :
393                         MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
394
395                 batch_reserve(info, 1);
396                 batch_dword(info, MI_FLUSH | flags);
397         }
398
399         batch_flush(info);
400 }
401
402 static drm_intel_bo *alloc_ibo(struct intel_info *info,
403                 const struct gralloc_drm_handle_t *handle,
404                 uint32_t *tiling, unsigned long *stride)
405 {
406         drm_intel_bo *ibo;
407         const char *name;
408         int aligned_width, aligned_height, bpp;
409         unsigned long flags;
410
411         flags = 0;
412         bpp = gralloc_drm_get_bpp(handle->format);
413         if (!bpp) {
414                 ALOGE("unrecognized format 0x%x", handle->format);
415                 return NULL;
416         }
417
418         aligned_width = handle->width;
419         aligned_height = handle->height;
420         gralloc_drm_align_geometry(handle->format,
421                         &aligned_width, &aligned_height);
422
423         if (handle->usage & GRALLOC_USAGE_HW_FB) {
424                 unsigned long max_stride;
425
426                 max_stride = 32 * 1024;
427                 if (info->gen < 50)
428                         max_stride /= 2;
429                 if (info->gen < 40)
430                         max_stride /= 2;
431
432                 name = "gralloc-fb";
433                 aligned_width = ALIGN(aligned_width, 64);
434                 flags = BO_ALLOC_FOR_RENDER;
435
436                 *tiling = I915_TILING_X;
437                 *stride = aligned_width * bpp;
438                 if (*stride > max_stride) {
439                         *tiling = I915_TILING_NONE;
440                         max_stride = 32 * 1024;
441                         if (*stride > max_stride)
442                                 return NULL;
443                 }
444
445                 while (1) {
446                         ibo = drm_intel_bo_alloc_tiled(info->bufmgr, name,
447                                         aligned_width, aligned_height,
448                                         bpp, tiling, stride, flags);
449                         if (!ibo || *stride > max_stride) {
450                                 if (ibo) {
451                                         drm_intel_bo_unreference(ibo);
452                                         ibo = NULL;
453                                 }
454
455                                 if (*tiling != I915_TILING_NONE) {
456                                         /* retry */
457                                         *tiling = I915_TILING_NONE;
458                                         max_stride = 32 * 1024;
459                                         continue;
460                                 }
461                         }
462                         if (ibo)
463                                 drm_intel_bo_disable_reuse(ibo);
464                         break;
465                 }
466         }
467         else {
468                 if (handle->usage & (GRALLOC_USAGE_SW_READ_OFTEN |
469                                      GRALLOC_USAGE_SW_WRITE_OFTEN))
470                         *tiling = I915_TILING_NONE;
471                 else if ((handle->usage & GRALLOC_USAGE_HW_RENDER) ||
472                          ((handle->usage & GRALLOC_USAGE_HW_TEXTURE) &&
473                           handle->width >= 64))
474                         *tiling = I915_TILING_X;
475                 else
476                         *tiling = I915_TILING_NONE;
477
478                 if (handle->usage & GRALLOC_USAGE_HW_TEXTURE) {
479                         name = "gralloc-texture";
480                         /* see 2D texture layout of DRI drivers */
481                         aligned_width = ALIGN(aligned_width, 4);
482                         aligned_height = ALIGN(aligned_height, 2);
483                 }
484                 else {
485                         name = "gralloc-buffer";
486                 }
487
488                 if (handle->usage & GRALLOC_USAGE_HW_RENDER)
489                         flags = BO_ALLOC_FOR_RENDER;
490
491                 ibo = drm_intel_bo_alloc_tiled(info->bufmgr, name,
492                                 aligned_width, aligned_height,
493                                 bpp, tiling, stride, flags);
494         }
495
496         return ibo;
497 }
498
499 static struct gralloc_drm_bo_t *intel_alloc(struct gralloc_drm_drv_t *drv,
500                 struct gralloc_drm_handle_t *handle)
501 {
502         struct intel_info *info = (struct intel_info *) drv;
503         struct intel_buffer *ib;
504
505         ib = calloc(1, sizeof(*ib));
506         if (!ib)
507                 return NULL;
508
509         if (handle->name) {
510                 uint32_t dummy;
511
512                 ib->ibo = drm_intel_bo_gem_create_from_name(info->bufmgr,
513                                 "gralloc-r", handle->name);
514                 if (!ib->ibo) {
515                         ALOGE("failed to create ibo from name %u",
516                                         handle->name);
517                         free(ib);
518                         return NULL;
519                 }
520
521                 if (drm_intel_bo_get_tiling(ib->ibo, &ib->tiling, &dummy)) {
522                         ALOGE("failed to get ibo tiling");
523                         drm_intel_bo_unreference(ib->ibo);
524                         free(ib);
525                         return NULL;
526                 }
527         }
528         else {
529                 unsigned long stride;
530
531                 ib->ibo = alloc_ibo(info, handle, &ib->tiling, &stride);
532                 if (!ib->ibo) {
533                         ALOGE("failed to allocate ibo %dx%d (format %d)",
534                                         handle->width,
535                                         handle->height,
536                                         handle->format);
537                         free(ib);
538                         return NULL;
539                 }
540
541                 handle->stride = stride;
542
543                 if (drm_intel_bo_flink(ib->ibo, (uint32_t *) &handle->name)) {
544                         ALOGE("failed to flink ibo");
545                         drm_intel_bo_unreference(ib->ibo);
546                         free(ib);
547                         return NULL;
548                 }
549         }
550
551         ib->base.fb_handle = ib->ibo->handle;
552
553         ib->base.handle = handle;
554
555         return &ib->base;
556 }
557
558 static void intel_free(struct gralloc_drm_drv_t *drv,
559                 struct gralloc_drm_bo_t *bo)
560 {
561         struct intel_buffer *ib = (struct intel_buffer *) bo;
562
563         drm_intel_bo_unreference(ib->ibo);
564         free(ib);
565 }
566
567 static int intel_map(struct gralloc_drm_drv_t *drv,
568                 struct gralloc_drm_bo_t *bo,
569                 int x, int y, int w, int h,
570                 int enable_write, void **addr)
571 {
572         struct intel_buffer *ib = (struct intel_buffer *) bo;
573         int err;
574
575         if (ib->tiling != I915_TILING_NONE ||
576             (ib->base.handle->usage & GRALLOC_USAGE_HW_FB))
577                 err = drm_intel_gem_bo_map_gtt(ib->ibo);
578         else
579                 err = drm_intel_bo_map(ib->ibo, enable_write);
580         if (!err)
581                 *addr = ib->ibo->virtual;
582
583         return err;
584 }
585
586 static void intel_unmap(struct gralloc_drm_drv_t *drv,
587                 struct gralloc_drm_bo_t *bo)
588 {
589         struct intel_buffer *ib = (struct intel_buffer *) bo;
590
591         if (ib->tiling != I915_TILING_NONE ||
592             (ib->base.handle->usage & GRALLOC_USAGE_HW_FB))
593                 drm_intel_gem_bo_unmap_gtt(ib->ibo);
594         else
595                 drm_intel_bo_unmap(ib->ibo);
596 }
597
598 #include "intel_chipset.h" /* for platform detection macros */
599 static void intel_init_kms_features(struct gralloc_drm_drv_t *drv,
600                 struct gralloc_drm_t *drm)
601 {
602         struct intel_info *info = (struct intel_info *) drv;
603         struct drm_i915_getparam gp;
604         int pageflipping, id, has_blt;
605
606         drm->mode_quirk_vmwgfx = 0;
607         /* why? */
608         drm->mode_sync_flip = 1;
609
610         memset(&gp, 0, sizeof(gp));
611         gp.param = I915_PARAM_HAS_PAGEFLIPPING;
612         gp.value = &pageflipping;
613         if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)))
614                 pageflipping = 0;
615
616         memset(&gp, 0, sizeof(gp));
617         gp.param = I915_PARAM_CHIPSET_ID;
618         gp.value = &id;
619         if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)))
620                 id = 0;
621
622         memset(&gp, 0, sizeof(gp));
623         gp.param = I915_PARAM_HAS_BLT;
624         gp.value = &has_blt;
625         if (drmCommandWriteRead(drm->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)))
626                 has_blt = 0;
627         info->exec_blt = has_blt ? I915_EXEC_BLT : 0;
628
629         /* GEN4, G4X, GEN5, GEN6, GEN7 */
630         if ((IS_9XX(id) || IS_G4X(id)) && !IS_GEN3(id)) {
631                 if (IS_GEN9(id))
632                         info->gen = 90;
633                 else if (IS_GEN8(id))
634                         info->gen = 80;
635                 else if (IS_GEN7(id))
636                         info->gen = 70;
637                 else if (IS_GEN6(id))
638                         info->gen = 60;
639                 else if (IS_GEN5(id))
640                         info->gen = 50;
641                 else
642                         info->gen = 40;
643         }
644         else {
645                 info->gen = 30;
646         }
647
648         if (pageflipping && info->gen > 30)
649                 drm->swap_mode = DRM_SWAP_FLIP;
650         else if (info->batch && info->gen == 30)
651                 drm->swap_mode = DRM_SWAP_COPY;
652         else
653                 drm->swap_mode = DRM_SWAP_SETCRTC;
654
655         if (drm->resources) {
656                 int pipe;
657
658                 pipe = drm_intel_get_pipe_from_crtc_id(info->bufmgr,
659                                 drm->primary->crtc_id);
660                 drm->swap_interval = (pipe >= 0) ? 1 : 0;
661                 drm->vblank_secondary = (pipe > 0);
662         }
663         else {
664                 drm->swap_interval = 0;
665         }
666
667         switch (drm->primary->fb_format) {
668         case HAL_PIXEL_FORMAT_BGRA_8888:
669         case HAL_PIXEL_FORMAT_RGB_565:
670                 break;
671         case HAL_PIXEL_FORMAT_RGBA_8888:
672                 if (drm->swap_mode == DRM_SWAP_FLIP)
673                         break;
674                 /* fall through */
675         default:
676                 drm->primary->fb_format = HAL_PIXEL_FORMAT_BGRA_8888;
677                 break;
678         }
679 }
680
681 static void intel_destroy(struct gralloc_drm_drv_t *drv)
682 {
683         struct intel_info *info = (struct intel_info *) drv;
684
685         batch_destroy(info);
686         drm_intel_bufmgr_destroy(info->bufmgr);
687         free(info);
688 }
689
690 struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd)
691 {
692         struct intel_info *info;
693
694         info = calloc(1, sizeof(*info));
695         if (!info) {
696                 ALOGE("failed to allocate driver info");
697                 return NULL;
698         }
699
700         info->fd = fd;
701         info->bufmgr = drm_intel_bufmgr_gem_init(info->fd, 16 * 1024);
702         if (!info->bufmgr) {
703                 ALOGE("failed to create buffer manager");
704                 free(info);
705                 return NULL;
706         }
707
708         batch_init(info);
709
710         info->base.destroy = intel_destroy;
711         info->base.init_kms_features = intel_init_kms_features;
712         info->base.alloc = intel_alloc;
713         info->base.free = intel_free;
714         info->base.map = intel_map;
715         info->base.unmap = intel_unmap;
716         info->base.blit = intel_blit;
717         info->base.resolve_format = intel_resolve_format;
718
719         return &info->base;
720 }