buffers.c revision b0ab5608
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#include "xf86drmMode.h" 41 42#include "buffers.h" 43 44struct bo 45{ 46 int fd; 47 void *ptr; 48 uint64_t size; 49 uint32_t pitch; 50 uint32_t handle; 51}; 52 53/* ----------------------------------------------------------------------------- 54 * Buffers management 55 */ 56 57static struct bo * 58bo_create_dumb(int fd, unsigned int width, unsigned int height, unsigned int bpp) 59{ 60 struct bo *bo; 61 int ret; 62 63 bo = calloc(1, sizeof(*bo)); 64 if (bo == NULL) { 65 fprintf(stderr, "failed to allocate buffer object\n"); 66 return NULL; 67 } 68 69 ret = drmModeCreateDumbBuffer(fd, width, height, bpp, 0, &bo->handle, 70 &bo->pitch, &bo->size); 71 if (ret) { 72 fprintf(stderr, "failed to create dumb buffer: %s\n", 73 strerror(errno)); 74 free(bo); 75 return NULL; 76 } 77 78 bo->fd = fd; 79 80 return bo; 81} 82 83static int bo_map(struct bo *bo, void **out) 84{ 85 void *map; 86 int ret; 87 uint64_t offset; 88 89 ret = drmModeMapDumbBuffer(bo->fd, bo->handle, &offset); 90 if (ret) 91 return ret; 92 93 map = drm_mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, 94 bo->fd, offset); 95 if (map == MAP_FAILED) 96 return -EINVAL; 97 98 bo->ptr = map; 99 *out = map; 100 101 return 0; 102} 103 104static void bo_unmap(struct bo *bo) 105{ 106 if (!bo->ptr) 107 return; 108 109 drm_munmap(bo->ptr, bo->size); 110 bo->ptr = NULL; 111} 112 113struct bo * 114bo_create(int fd, unsigned int format, 115 unsigned int width, unsigned int height, 116 unsigned int handles[4], unsigned int pitches[4], 117 unsigned int offsets[4], enum util_fill_pattern pattern) 118{ 119 unsigned int virtual_height; 120 struct bo *bo; 121 unsigned int bpp; 122 void *planes[3] = { 0, }; 123 void *virtual; 124 int ret; 125 126 switch (format) { 127 case DRM_FORMAT_C8: 128 case DRM_FORMAT_NV12: 129 case DRM_FORMAT_NV21: 130 case DRM_FORMAT_NV16: 131 case DRM_FORMAT_NV61: 132 case DRM_FORMAT_YUV420: 133 case DRM_FORMAT_YVU420: 134 bpp = 8; 135 break; 136 137 case DRM_FORMAT_ARGB4444: 138 case DRM_FORMAT_XRGB4444: 139 case DRM_FORMAT_ABGR4444: 140 case DRM_FORMAT_XBGR4444: 141 case DRM_FORMAT_RGBA4444: 142 case DRM_FORMAT_RGBX4444: 143 case DRM_FORMAT_BGRA4444: 144 case DRM_FORMAT_BGRX4444: 145 case DRM_FORMAT_ARGB1555: 146 case DRM_FORMAT_XRGB1555: 147 case DRM_FORMAT_ABGR1555: 148 case DRM_FORMAT_XBGR1555: 149 case DRM_FORMAT_RGBA5551: 150 case DRM_FORMAT_RGBX5551: 151 case DRM_FORMAT_BGRA5551: 152 case DRM_FORMAT_BGRX5551: 153 case DRM_FORMAT_RGB565: 154 case DRM_FORMAT_BGR565: 155 case DRM_FORMAT_UYVY: 156 case DRM_FORMAT_VYUY: 157 case DRM_FORMAT_YUYV: 158 case DRM_FORMAT_YVYU: 159 bpp = 16; 160 break; 161 162 case DRM_FORMAT_BGR888: 163 case DRM_FORMAT_RGB888: 164 bpp = 24; 165 break; 166 167 case DRM_FORMAT_ARGB8888: 168 case DRM_FORMAT_XRGB8888: 169 case DRM_FORMAT_ABGR8888: 170 case DRM_FORMAT_XBGR8888: 171 case DRM_FORMAT_RGBA8888: 172 case DRM_FORMAT_RGBX8888: 173 case DRM_FORMAT_BGRA8888: 174 case DRM_FORMAT_BGRX8888: 175 case DRM_FORMAT_ARGB2101010: 176 case DRM_FORMAT_XRGB2101010: 177 case DRM_FORMAT_ABGR2101010: 178 case DRM_FORMAT_XBGR2101010: 179 case DRM_FORMAT_RGBA1010102: 180 case DRM_FORMAT_RGBX1010102: 181 case DRM_FORMAT_BGRA1010102: 182 case DRM_FORMAT_BGRX1010102: 183 bpp = 32; 184 break; 185 186 case DRM_FORMAT_XRGB16161616F: 187 case DRM_FORMAT_XBGR16161616F: 188 case DRM_FORMAT_ARGB16161616F: 189 case DRM_FORMAT_ABGR16161616F: 190 bpp = 64; 191 break; 192 193 default: 194 fprintf(stderr, "unsupported format 0x%08x\n", format); 195 return NULL; 196 } 197 198 switch (format) { 199 case DRM_FORMAT_NV12: 200 case DRM_FORMAT_NV21: 201 case DRM_FORMAT_YUV420: 202 case DRM_FORMAT_YVU420: 203 virtual_height = height * 3 / 2; 204 break; 205 206 case DRM_FORMAT_NV16: 207 case DRM_FORMAT_NV61: 208 virtual_height = height * 2; 209 break; 210 211 default: 212 virtual_height = height; 213 break; 214 } 215 216 bo = bo_create_dumb(fd, width, virtual_height, bpp); 217 if (!bo) 218 return NULL; 219 220 ret = bo_map(bo, &virtual); 221 if (ret) { 222 fprintf(stderr, "failed to map buffer: %s\n", 223 strerror(-errno)); 224 bo_destroy(bo); 225 return NULL; 226 } 227 228 /* just testing a limited # of formats to test single 229 * and multi-planar path.. would be nice to add more.. 230 */ 231 switch (format) { 232 case DRM_FORMAT_UYVY: 233 case DRM_FORMAT_VYUY: 234 case DRM_FORMAT_YUYV: 235 case DRM_FORMAT_YVYU: 236 offsets[0] = 0; 237 handles[0] = bo->handle; 238 pitches[0] = bo->pitch; 239 240 planes[0] = virtual; 241 break; 242 243 case DRM_FORMAT_NV12: 244 case DRM_FORMAT_NV21: 245 case DRM_FORMAT_NV16: 246 case DRM_FORMAT_NV61: 247 offsets[0] = 0; 248 handles[0] = bo->handle; 249 pitches[0] = bo->pitch; 250 pitches[1] = pitches[0]; 251 offsets[1] = pitches[0] * height; 252 handles[1] = bo->handle; 253 254 planes[0] = virtual; 255 planes[1] = virtual + offsets[1]; 256 break; 257 258 case DRM_FORMAT_YUV420: 259 case DRM_FORMAT_YVU420: 260 offsets[0] = 0; 261 handles[0] = bo->handle; 262 pitches[0] = bo->pitch; 263 pitches[1] = pitches[0] / 2; 264 offsets[1] = pitches[0] * height; 265 handles[1] = bo->handle; 266 pitches[2] = pitches[1]; 267 offsets[2] = offsets[1] + pitches[1] * height / 2; 268 handles[2] = bo->handle; 269 270 planes[0] = virtual; 271 planes[1] = virtual + offsets[1]; 272 planes[2] = virtual + offsets[2]; 273 break; 274 275 case DRM_FORMAT_C8: 276 case DRM_FORMAT_ARGB4444: 277 case DRM_FORMAT_XRGB4444: 278 case DRM_FORMAT_ABGR4444: 279 case DRM_FORMAT_XBGR4444: 280 case DRM_FORMAT_RGBA4444: 281 case DRM_FORMAT_RGBX4444: 282 case DRM_FORMAT_BGRA4444: 283 case DRM_FORMAT_BGRX4444: 284 case DRM_FORMAT_ARGB1555: 285 case DRM_FORMAT_XRGB1555: 286 case DRM_FORMAT_ABGR1555: 287 case DRM_FORMAT_XBGR1555: 288 case DRM_FORMAT_RGBA5551: 289 case DRM_FORMAT_RGBX5551: 290 case DRM_FORMAT_BGRA5551: 291 case DRM_FORMAT_BGRX5551: 292 case DRM_FORMAT_RGB565: 293 case DRM_FORMAT_BGR565: 294 case DRM_FORMAT_BGR888: 295 case DRM_FORMAT_RGB888: 296 case DRM_FORMAT_ARGB8888: 297 case DRM_FORMAT_XRGB8888: 298 case DRM_FORMAT_ABGR8888: 299 case DRM_FORMAT_XBGR8888: 300 case DRM_FORMAT_RGBA8888: 301 case DRM_FORMAT_RGBX8888: 302 case DRM_FORMAT_BGRA8888: 303 case DRM_FORMAT_BGRX8888: 304 case DRM_FORMAT_ARGB2101010: 305 case DRM_FORMAT_XRGB2101010: 306 case DRM_FORMAT_ABGR2101010: 307 case DRM_FORMAT_XBGR2101010: 308 case DRM_FORMAT_RGBA1010102: 309 case DRM_FORMAT_RGBX1010102: 310 case DRM_FORMAT_BGRA1010102: 311 case DRM_FORMAT_BGRX1010102: 312 case DRM_FORMAT_XRGB16161616F: 313 case DRM_FORMAT_XBGR16161616F: 314 case DRM_FORMAT_ARGB16161616F: 315 case DRM_FORMAT_ABGR16161616F: 316 offsets[0] = 0; 317 handles[0] = bo->handle; 318 pitches[0] = bo->pitch; 319 320 planes[0] = virtual; 321 break; 322 } 323 324 util_fill_pattern(format, pattern, planes, width, height, pitches[0]); 325 bo_unmap(bo); 326 327 return bo; 328} 329 330void bo_destroy(struct bo *bo) 331{ 332 int ret; 333 334 ret = drmModeDestroyDumbBuffer(bo->fd, bo->handle); 335 if (ret) 336 fprintf(stderr, "failed to destroy dumb buffer: %s\n", 337 strerror(errno)); 338 339 free(bo); 340} 341