vc4_bufmgr.c revision 848b8605
1/* 2 * Copyright © 2014 Broadcom 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include <errno.h> 25#include <err.h> 26#include <stdio.h> 27#include <sys/mman.h> 28#include <xf86drm.h> 29#include <xf86drmMode.h> 30 31#include "util/u_memory.h" 32 33#include "vc4_context.h" 34#include "vc4_screen.h" 35 36struct vc4_bo * 37vc4_bo_alloc(struct vc4_screen *screen, uint32_t size, const char *name) 38{ 39 struct vc4_bo *bo = CALLOC_STRUCT(vc4_bo); 40 if (!bo) 41 return NULL; 42 43 pipe_reference_init(&bo->reference, 1); 44 bo->screen = screen; 45 bo->size = size; 46 bo->name = name; 47 48 struct drm_mode_create_dumb create; 49 memset(&create, 0, sizeof(create)); 50 51 create.width = 128; 52 create.bpp = 8; 53 create.height = (size + 127) / 128; 54 55 int ret = drmIoctl(screen->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create); 56 if (ret != 0) 57 errx(1, "create ioctl"); 58 59 bo->handle = create.handle; 60 assert(create.size >= size); 61 62 return bo; 63} 64 65void 66vc4_bo_free(struct vc4_bo *bo) 67{ 68 struct vc4_screen *screen = bo->screen; 69 70 if (bo->map) { 71#ifdef USE_VC4_SIMULATOR 72 if (bo->simulator_winsys_map) { 73 free(bo->map); 74 bo->map = bo->simulator_winsys_map; 75 } 76#endif 77 munmap(bo->map, bo->size); 78 } 79 80 struct drm_gem_close c; 81 c.handle = bo->handle; 82 int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_CLOSE, &c); 83 if (ret != 0) 84 fprintf(stderr, "close object %d: %s\n", bo->handle, strerror(errno)); 85 86 free(bo); 87} 88 89struct vc4_bo * 90vc4_bo_open_name(struct vc4_screen *screen, uint32_t name, 91 uint32_t winsys_stride) 92{ 93 struct vc4_bo *bo = CALLOC_STRUCT(vc4_bo); 94 95 struct drm_gem_open o; 96 o.name = name; 97 int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o); 98 if (ret) { 99 fprintf(stderr, "Failed to open bo %d: %s\n", 100 name, strerror(errno)); 101 free(bo); 102 return NULL; 103 } 104 105 pipe_reference_init(&bo->reference, 1); 106 bo->screen = screen; 107 bo->handle = o.handle; 108 bo->size = o.size; 109 bo->name = "winsys"; 110 111#ifdef USE_VC4_SIMULATOR 112 vc4_bo_map(bo); 113 bo->simulator_winsys_map = bo->map; 114 bo->simulator_winsys_stride = winsys_stride; 115 bo->map = malloc(bo->size); 116#endif 117 118 return bo; 119} 120 121struct vc4_bo * 122vc4_bo_alloc_mem(struct vc4_screen *screen, const void *data, uint32_t size, 123 const char *name) 124{ 125 void *map; 126 struct vc4_bo *bo; 127 128 bo = vc4_bo_alloc(screen, size, name); 129 map = vc4_bo_map(bo); 130 memcpy(map, data, size); 131 return bo; 132} 133 134bool 135vc4_bo_flink(struct vc4_bo *bo, uint32_t *name) 136{ 137 struct drm_gem_flink flink = { 138 .handle = bo->handle, 139 }; 140 int ret = drmIoctl(bo->screen->fd, DRM_IOCTL_GEM_FLINK, &flink); 141 if (ret) { 142 fprintf(stderr, "Failed to flink bo %d: %s\n", 143 bo->handle, strerror(errno)); 144 free(bo); 145 return false; 146 } 147 148 *name = flink.name; 149 150 return true; 151} 152 153void * 154vc4_bo_map(struct vc4_bo *bo) 155{ 156 int ret; 157 158 if (bo->map) 159 return bo->map; 160 161 struct drm_mode_map_dumb map; 162 memset(&map, 0, sizeof(map)); 163 map.handle = bo->handle; 164 ret = drmIoctl(bo->screen->fd, DRM_IOCTL_MODE_MAP_DUMB, &map); 165 if (ret != 0) 166 errx(1, "map ioctl"); 167 168 bo->map = mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, 169 bo->screen->fd, map.offset); 170 if (bo->map == MAP_FAILED) { 171 errx(1, "mmap of bo %d (offset 0x%016llx, size %d) failed\n", 172 bo->handle, (long long)map.offset, bo->size); 173 } 174 175 return bo->map; 176} 177