native_drm.c revision e7424d72405a1cb1fb5ac625b340043aaa9f88be
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.8 4 * 5 * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 */ 25 26#include <sys/types.h> 27#include <sys/stat.h> 28#include <fcntl.h> 29 30#include "util/u_memory.h" 31#include "egllog.h" 32 33#include "native_drm.h" 34 35/* see get_drm_screen_name */ 36#include <radeon_drm.h> 37#include "radeon/drm/radeon_drm.h" 38 39static boolean 40kms_display_is_format_supported(struct native_display *ndpy, 41 enum pipe_format fmt, boolean is_color) 42{ 43 return ndpy->screen->is_format_supported(ndpy->screen, 44 fmt, PIPE_TEXTURE_2D, 0, 45 (is_color) ? PIPE_BIND_RENDER_TARGET : 46 PIPE_BIND_DEPTH_STENCIL, 0); 47} 48 49static const struct native_config ** 50kms_display_get_configs(struct native_display *ndpy, int *num_configs) 51{ 52 struct kms_display *kdpy = kms_display(ndpy); 53 const struct native_config **configs; 54 55 /* first time */ 56 if (!kdpy->config) { 57 struct native_config *nconf; 58 enum pipe_format format; 59 60 kdpy->config = CALLOC(1, sizeof(*kdpy->config)); 61 if (!kdpy->config) 62 return NULL; 63 64 nconf = &kdpy->config->base; 65 66 nconf->buffer_mask = 67 (1 << NATIVE_ATTACHMENT_FRONT_LEFT) | 68 (1 << NATIVE_ATTACHMENT_BACK_LEFT); 69 70 format = PIPE_FORMAT_B8G8R8A8_UNORM; 71 if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) { 72 format = PIPE_FORMAT_A8R8G8B8_UNORM; 73 if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) 74 format = PIPE_FORMAT_NONE; 75 } 76 if (format == PIPE_FORMAT_NONE) { 77 FREE(kdpy->config); 78 kdpy->config = NULL; 79 return NULL; 80 } 81 82 nconf->color_format = format; 83 84 /* support KMS */ 85 if (kdpy->resources) 86 nconf->scanout_bit = TRUE; 87 } 88 89 configs = MALLOC(sizeof(*configs)); 90 if (configs) { 91 configs[0] = &kdpy->config->base; 92 if (num_configs) 93 *num_configs = 1; 94 } 95 96 return configs; 97} 98 99static int 100kms_display_get_param(struct native_display *ndpy, 101 enum native_param_type param) 102{ 103 int val; 104 105 switch (param) { 106 default: 107 val = 0; 108 break; 109 } 110 111 return val; 112} 113 114static void 115kms_display_destroy(struct native_display *ndpy) 116{ 117 struct kms_display *kdpy = kms_display(ndpy); 118 119 if (kdpy->config) 120 FREE(kdpy->config); 121 122 kms_display_fini_modeset(&kdpy->base); 123 124 if (kdpy->base.screen) 125 kdpy->base.screen->destroy(kdpy->base.screen); 126 127 if (kdpy->fd >= 0) 128 close(kdpy->fd); 129 130 FREE(kdpy); 131} 132 133static const char * 134get_drm_screen_name(int fd, drmVersionPtr version) 135{ 136 const char *name = version->name; 137 138 if (name && !strcmp(name, "radeon")) { 139 int chip_id; 140 struct drm_radeon_info info; 141 142 memset(&info, 0, sizeof(info)); 143 info.request = RADEON_INFO_DEVICE_ID; 144 info.value = pointer_to_intptr(&chip_id); 145 if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) 146 return NULL; 147 148 name = is_r3xx(chip_id) ? "r300" : "r600"; 149 } 150 151 return name; 152} 153 154/** 155 * Initialize KMS and pipe screen. 156 */ 157static boolean 158kms_display_init_screen(struct native_display *ndpy) 159{ 160 struct kms_display *kdpy = kms_display(ndpy); 161 drmVersionPtr version; 162 const char *name; 163 164 version = drmGetVersion(kdpy->fd); 165 if (!version) { 166 _eglLog(_EGL_WARNING, "invalid fd %d", kdpy->fd); 167 return FALSE; 168 } 169 170 name = get_drm_screen_name(kdpy->fd, version); 171 if (name) { 172 kdpy->base.screen = 173 kdpy->event_handler->new_drm_screen(&kdpy->base, name, kdpy->fd); 174 } 175 drmFreeVersion(version); 176 177 if (!kdpy->base.screen) { 178 _eglLog(_EGL_WARNING, "failed to create DRM screen"); 179 return FALSE; 180 } 181 182 return TRUE; 183} 184 185static struct native_display * 186kms_create_display(int fd, struct native_event_handler *event_handler, 187 void *user_data) 188{ 189 struct kms_display *kdpy; 190 191 kdpy = CALLOC_STRUCT(kms_display); 192 if (!kdpy) 193 return NULL; 194 195 kdpy->fd = fd; 196 kdpy->event_handler = event_handler; 197 kdpy->base.user_data = user_data; 198 199 if (!kms_display_init_screen(&kdpy->base)) { 200 kms_display_destroy(&kdpy->base); 201 return NULL; 202 } 203 204 kdpy->base.destroy = kms_display_destroy; 205 kdpy->base.get_param = kms_display_get_param; 206 kdpy->base.get_configs = kms_display_get_configs; 207 208 kms_display_init_modeset(&kdpy->base); 209 210 return &kdpy->base; 211} 212 213static struct native_display * 214native_create_display(void *dpy, struct native_event_handler *event_handler, 215 void *user_data) 216{ 217 int fd; 218 219 if (dpy) { 220 fd = dup((int) pointer_to_intptr(dpy)); 221 } 222 else { 223 fd = open("/dev/dri/card0", O_RDWR); 224 } 225 if (fd < 0) 226 return NULL; 227 228 return kms_create_display(fd, event_handler, user_data); 229} 230 231static const struct native_platform drm_platform = { 232 "DRM", /* name */ 233 native_create_display 234}; 235 236const struct native_platform * 237native_get_drm_platform(void) 238{ 239 return &drm_platform; 240} 241