OSDN Git Service

modetest: add FP16 format support
[android-x86/external-libdrm.git] / tests / modetest / buffers.c
1 /*
2  * DRM based mode setting test program
3  * Copyright 2008 Tungsten Graphics
4  *   Jakob Bornecrantz <jakob@tungstengraphics.com>
5  * Copyright 2008 Intel Corporation
6  *   Jesse Barnes <jesse.barnes@intel.com>
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24  * IN THE SOFTWARE.
25  */
26
27 #include <assert.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <string.h>
33 #include <sys/ioctl.h>
34
35 #include "drm.h"
36 #include "drm_fourcc.h"
37
38 #include "libdrm_macros.h"
39 #include "xf86drm.h"
40
41 #include "buffers.h"
42
43 struct bo
44 {
45         int fd;
46         void *ptr;
47         size_t size;
48         size_t offset;
49         size_t pitch;
50         unsigned handle;
51 };
52
53 /* -----------------------------------------------------------------------------
54  * Buffers management
55  */
56
57 static struct bo *
58 bo_create_dumb(int fd, unsigned int width, unsigned int height, unsigned int bpp)
59 {
60         struct drm_mode_create_dumb arg;
61         struct bo *bo;
62         int ret;
63
64         bo = calloc(1, sizeof(*bo));
65         if (bo == NULL) {
66                 fprintf(stderr, "failed to allocate buffer object\n");
67                 return NULL;
68         }
69
70         memset(&arg, 0, sizeof(arg));
71         arg.bpp = bpp;
72         arg.width = width;
73         arg.height = height;
74
75         ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
76         if (ret) {
77                 fprintf(stderr, "failed to create dumb buffer: %s\n",
78                         strerror(errno));
79                 free(bo);
80                 return NULL;
81         }
82
83         bo->fd = fd;
84         bo->handle = arg.handle;
85         bo->size = arg.size;
86         bo->pitch = arg.pitch;
87
88         return bo;
89 }
90
91 static int bo_map(struct bo *bo, void **out)
92 {
93         struct drm_mode_map_dumb arg;
94         void *map;
95         int ret;
96
97         memset(&arg, 0, sizeof(arg));
98         arg.handle = bo->handle;
99
100         ret = drmIoctl(bo->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
101         if (ret)
102                 return ret;
103
104         map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
105                        bo->fd, arg.offset);
106         if (map == MAP_FAILED)
107                 return -EINVAL;
108
109         bo->ptr = map;
110         *out = map;
111
112         return 0;
113 }
114
115 static void bo_unmap(struct bo *bo)
116 {
117         if (!bo->ptr)
118                 return;
119
120         drm_munmap(bo->ptr, bo->size);
121         bo->ptr = NULL;
122 }
123
124 struct bo *
125 bo_create(int fd, unsigned int format,
126           unsigned int width, unsigned int height,
127           unsigned int handles[4], unsigned int pitches[4],
128           unsigned int offsets[4], enum util_fill_pattern pattern)
129 {
130         unsigned int virtual_height;
131         struct bo *bo;
132         unsigned int bpp;
133         void *planes[3] = { 0, };
134         void *virtual;
135         int ret;
136
137         switch (format) {
138         case DRM_FORMAT_C8:
139         case DRM_FORMAT_NV12:
140         case DRM_FORMAT_NV21:
141         case DRM_FORMAT_NV16:
142         case DRM_FORMAT_NV61:
143         case DRM_FORMAT_YUV420:
144         case DRM_FORMAT_YVU420:
145                 bpp = 8;
146                 break;
147
148         case DRM_FORMAT_ARGB4444:
149         case DRM_FORMAT_XRGB4444:
150         case DRM_FORMAT_ABGR4444:
151         case DRM_FORMAT_XBGR4444:
152         case DRM_FORMAT_RGBA4444:
153         case DRM_FORMAT_RGBX4444:
154         case DRM_FORMAT_BGRA4444:
155         case DRM_FORMAT_BGRX4444:
156         case DRM_FORMAT_ARGB1555:
157         case DRM_FORMAT_XRGB1555:
158         case DRM_FORMAT_ABGR1555:
159         case DRM_FORMAT_XBGR1555:
160         case DRM_FORMAT_RGBA5551:
161         case DRM_FORMAT_RGBX5551:
162         case DRM_FORMAT_BGRA5551:
163         case DRM_FORMAT_BGRX5551:
164         case DRM_FORMAT_RGB565:
165         case DRM_FORMAT_BGR565:
166         case DRM_FORMAT_UYVY:
167         case DRM_FORMAT_VYUY:
168         case DRM_FORMAT_YUYV:
169         case DRM_FORMAT_YVYU:
170                 bpp = 16;
171                 break;
172
173         case DRM_FORMAT_BGR888:
174         case DRM_FORMAT_RGB888:
175                 bpp = 24;
176                 break;
177
178         case DRM_FORMAT_ARGB8888:
179         case DRM_FORMAT_XRGB8888:
180         case DRM_FORMAT_ABGR8888:
181         case DRM_FORMAT_XBGR8888:
182         case DRM_FORMAT_RGBA8888:
183         case DRM_FORMAT_RGBX8888:
184         case DRM_FORMAT_BGRA8888:
185         case DRM_FORMAT_BGRX8888:
186         case DRM_FORMAT_ARGB2101010:
187         case DRM_FORMAT_XRGB2101010:
188         case DRM_FORMAT_ABGR2101010:
189         case DRM_FORMAT_XBGR2101010:
190         case DRM_FORMAT_RGBA1010102:
191         case DRM_FORMAT_RGBX1010102:
192         case DRM_FORMAT_BGRA1010102:
193         case DRM_FORMAT_BGRX1010102:
194                 bpp = 32;
195                 break;
196
197         case DRM_FORMAT_XRGB16161616F:
198         case DRM_FORMAT_XBGR16161616F:
199         case DRM_FORMAT_ARGB16161616F:
200         case DRM_FORMAT_ABGR16161616F:
201                 bpp = 64;
202                 break;
203
204         default:
205                 fprintf(stderr, "unsupported format 0x%08x\n",  format);
206                 return NULL;
207         }
208
209         switch (format) {
210         case DRM_FORMAT_NV12:
211         case DRM_FORMAT_NV21:
212         case DRM_FORMAT_YUV420:
213         case DRM_FORMAT_YVU420:
214                 virtual_height = height * 3 / 2;
215                 break;
216
217         case DRM_FORMAT_NV16:
218         case DRM_FORMAT_NV61:
219                 virtual_height = height * 2;
220                 break;
221
222         default:
223                 virtual_height = height;
224                 break;
225         }
226
227         bo = bo_create_dumb(fd, width, virtual_height, bpp);
228         if (!bo)
229                 return NULL;
230
231         ret = bo_map(bo, &virtual);
232         if (ret) {
233                 fprintf(stderr, "failed to map buffer: %s\n",
234                         strerror(-errno));
235                 bo_destroy(bo);
236                 return NULL;
237         }
238
239         /* just testing a limited # of formats to test single
240          * and multi-planar path.. would be nice to add more..
241          */
242         switch (format) {
243         case DRM_FORMAT_UYVY:
244         case DRM_FORMAT_VYUY:
245         case DRM_FORMAT_YUYV:
246         case DRM_FORMAT_YVYU:
247                 offsets[0] = 0;
248                 handles[0] = bo->handle;
249                 pitches[0] = bo->pitch;
250
251                 planes[0] = virtual;
252                 break;
253
254         case DRM_FORMAT_NV12:
255         case DRM_FORMAT_NV21:
256         case DRM_FORMAT_NV16:
257         case DRM_FORMAT_NV61:
258                 offsets[0] = 0;
259                 handles[0] = bo->handle;
260                 pitches[0] = bo->pitch;
261                 pitches[1] = pitches[0];
262                 offsets[1] = pitches[0] * height;
263                 handles[1] = bo->handle;
264
265                 planes[0] = virtual;
266                 planes[1] = virtual + offsets[1];
267                 break;
268
269         case DRM_FORMAT_YUV420:
270         case DRM_FORMAT_YVU420:
271                 offsets[0] = 0;
272                 handles[0] = bo->handle;
273                 pitches[0] = bo->pitch;
274                 pitches[1] = pitches[0] / 2;
275                 offsets[1] = pitches[0] * height;
276                 handles[1] = bo->handle;
277                 pitches[2] = pitches[1];
278                 offsets[2] = offsets[1] + pitches[1] * height / 2;
279                 handles[2] = bo->handle;
280
281                 planes[0] = virtual;
282                 planes[1] = virtual + offsets[1];
283                 planes[2] = virtual + offsets[2];
284                 break;
285
286         case DRM_FORMAT_C8:
287         case DRM_FORMAT_ARGB4444:
288         case DRM_FORMAT_XRGB4444:
289         case DRM_FORMAT_ABGR4444:
290         case DRM_FORMAT_XBGR4444:
291         case DRM_FORMAT_RGBA4444:
292         case DRM_FORMAT_RGBX4444:
293         case DRM_FORMAT_BGRA4444:
294         case DRM_FORMAT_BGRX4444:
295         case DRM_FORMAT_ARGB1555:
296         case DRM_FORMAT_XRGB1555:
297         case DRM_FORMAT_ABGR1555:
298         case DRM_FORMAT_XBGR1555:
299         case DRM_FORMAT_RGBA5551:
300         case DRM_FORMAT_RGBX5551:
301         case DRM_FORMAT_BGRA5551:
302         case DRM_FORMAT_BGRX5551:
303         case DRM_FORMAT_RGB565:
304         case DRM_FORMAT_BGR565:
305         case DRM_FORMAT_BGR888:
306         case DRM_FORMAT_RGB888:
307         case DRM_FORMAT_ARGB8888:
308         case DRM_FORMAT_XRGB8888:
309         case DRM_FORMAT_ABGR8888:
310         case DRM_FORMAT_XBGR8888:
311         case DRM_FORMAT_RGBA8888:
312         case DRM_FORMAT_RGBX8888:
313         case DRM_FORMAT_BGRA8888:
314         case DRM_FORMAT_BGRX8888:
315         case DRM_FORMAT_ARGB2101010:
316         case DRM_FORMAT_XRGB2101010:
317         case DRM_FORMAT_ABGR2101010:
318         case DRM_FORMAT_XBGR2101010:
319         case DRM_FORMAT_RGBA1010102:
320         case DRM_FORMAT_RGBX1010102:
321         case DRM_FORMAT_BGRA1010102:
322         case DRM_FORMAT_BGRX1010102:
323         case DRM_FORMAT_XRGB16161616F:
324         case DRM_FORMAT_XBGR16161616F:
325         case DRM_FORMAT_ARGB16161616F:
326         case DRM_FORMAT_ABGR16161616F:
327                 offsets[0] = 0;
328                 handles[0] = bo->handle;
329                 pitches[0] = bo->pitch;
330
331                 planes[0] = virtual;
332                 break;
333         }
334
335         util_fill_pattern(format, pattern, planes, width, height, pitches[0]);
336         bo_unmap(bo);
337
338         return bo;
339 }
340
341 void bo_destroy(struct bo *bo)
342 {
343         struct drm_mode_destroy_dumb arg;
344         int ret;
345
346         memset(&arg, 0, sizeof(arg));
347         arg.handle = bo->handle;
348
349         ret = drmIoctl(bo->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
350         if (ret)
351                 fprintf(stderr, "failed to destroy dumb buffer: %s\n",
352                         strerror(errno));
353
354         free(bo);
355 }