7 #include "egl_tracker.h"
12 #include "state_tracker/drm_api.h"
14 #include "pipe/p_screen.h"
15 #include "pipe/internal/p_winsys_screen.h"
25 /** Called by libEGL just prior to unloading/closing the driver.
28 drm_unload(_EGLDriver
*drv
)
34 * The bootstrap function. Return a new drm_driver object and
35 * plug in API functions.
36 * libEGL finds this function with dlopen()/dlsym() and calls it from
37 * "load driver" function.
40 _eglMain(const char *args
)
44 drv
= (_EGLDriver
*) calloc(1, sizeof(_EGLDriver
));
49 /* First fill in the dispatch table with defaults */
50 _eglInitDriverFallbacks(drv
);
51 /* then plug in our Drm-specific functions */
52 drv
->API
.Initialize
= drm_initialize
;
53 drv
->API
.Terminate
= drm_terminate
;
54 drv
->API
.CreateContext
= drm_create_context
;
55 drv
->API
.MakeCurrent
= drm_make_current
;
56 drv
->API
.CreateWindowSurface
= drm_create_window_surface
;
57 drv
->API
.CreatePixmapSurface
= drm_create_pixmap_surface
;
58 drv
->API
.CreatePbufferSurface
= drm_create_pbuffer_surface
;
59 drv
->API
.DestroySurface
= drm_destroy_surface
;
60 drv
->API
.DestroyContext
= drm_destroy_context
;
61 drv
->API
.CreateScreenSurfaceMESA
= drm_create_screen_surface_mesa
;
62 drv
->API
.ShowScreenSurfaceMESA
= drm_show_screen_surface_mesa
;
63 drv
->API
.SwapBuffers
= drm_swap_buffers
;
65 drv
->Name
= "DRM/Gallium/Win";
66 drv
->Unload
= drm_unload
;
72 drm_get_device_id(struct drm_device
*device
)
78 /* TODO get the real minor */
83 snprintf(path
, sizeof(path
), "/sys/class/drm/card%d/device/device", minor
);
84 file
= fopen(path
, "r");
86 _eglLog(_EGL_WARNING
, "Could not retrive device ID\n");
90 ret
= fgets(path
, sizeof( path
), file
);
95 sscanf(path
, "%x", &device
->deviceID
);
99 drm_update_res(struct drm_device
*dev
)
101 drmModeFreeResources(dev
->res
);
102 dev
->res
= drmModeGetResources(dev
->drmFD
);
106 drm_add_modes_from_connector(_EGLScreen
*screen
, drmModeConnectorPtr connector
)
108 drmModeModeInfoPtr m
= NULL
;
111 for (i
= 0; i
< connector
->count_modes
; i
++) {
112 m
= &connector
->modes
[i
];
113 _eglAddNewMode(screen
, m
->hdisplay
, m
->vdisplay
, m
->vrefresh
, m
->name
);
118 drm_find_dpms(struct drm_device
*dev
, struct drm_screen
*screen
)
120 drmModeConnectorPtr c
= screen
->connector
;
121 drmModePropertyPtr p
;
124 for (i
= 0; i
< c
->count_props
; i
++) {
125 p
= drmModeGetProperty(dev
->drmFD
, c
->props
[i
]);
126 if (!strcmp(p
->name
, "DPMS"))
129 drmModeFreeProperty(p
);
136 static int drm_open_minor(int minor
)
140 sprintf(buf
, DRM_DEV_NAME
, DRM_DIR_NAME
, minor
);
141 return open(buf
, O_RDWR
, 0);
145 drm_initialize(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLint
*major
, EGLint
*minor
)
147 struct drm_device
*dev
;
148 struct drm_screen
*screen
= NULL
;
149 drmModeConnectorPtr connector
= NULL
;
150 drmModeResPtr res
= NULL
;
151 unsigned count_connectors
= 0;
156 dev
= (struct drm_device
*) calloc(1, sizeof(struct drm_device
));
159 dev
->api
= drm_api_create();
161 /* try the first node */
162 fd
= drm_open_minor(0);
167 drm_get_device_id(dev
);
169 dev
->screen
= dev
->api
->create_screen(dev
->api
, dev
->drmFD
, NULL
);
172 dev
->winsys
= dev
->screen
->winsys
;
174 driInitExtensions(NULL
, NULL
, GL_FALSE
);
179 count_connectors
= res
->count_connectors
;
181 _eglLog(_EGL_WARNING
, "Could not retrive kms information\n");
183 for(i
= 0; i
< count_connectors
&& i
< MAX_SCREENS
; i
++) {
184 connector
= drmModeGetConnector(fd
, res
->connectors
[i
]);
189 if (connector
->connection
!= DRM_MODE_CONNECTED
) {
190 drmModeFreeConnector(connector
);
194 screen
= malloc(sizeof(struct drm_screen
));
195 memset(screen
, 0, sizeof(*screen
));
196 screen
->connector
= connector
;
197 screen
->connectorID
= connector
->connector_id
;
198 _eglInitScreen(&screen
->base
);
199 _eglAddScreen(disp
, &screen
->base
);
200 drm_add_modes_from_connector(&screen
->base
, connector
);
201 drm_find_dpms(dev
, screen
);
202 dev
->screens
[num_screens
++] = screen
;
204 dev
->count_screens
= num_screens
;
206 disp
->DriverData
= dev
;
208 /* for now we only have one config */
209 _EGLConfig
*config
= calloc(1, sizeof(*config
));
210 memset(config
, 1, sizeof(*config
));
211 _eglInitConfig(config
, 1);
212 _eglSetConfigAttrib(config
, EGL_RED_SIZE
, 8);
213 _eglSetConfigAttrib(config
, EGL_GREEN_SIZE
, 8);
214 _eglSetConfigAttrib(config
, EGL_BLUE_SIZE
, 8);
215 _eglSetConfigAttrib(config
, EGL_ALPHA_SIZE
, 8);
216 _eglSetConfigAttrib(config
, EGL_BUFFER_SIZE
, 32);
217 _eglSetConfigAttrib(config
, EGL_DEPTH_SIZE
, 24);
218 _eglSetConfigAttrib(config
, EGL_STENCIL_SIZE
, 8);
219 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_PBUFFER_BIT
);
220 _eglAddConfig(disp
, config
);
222 disp
->ClientAPIsMask
= EGL_OPENGL_BIT
/*| EGL_OPENGL_ES_BIT*/;
223 /* enable supported extensions */
224 disp
->Extensions
.MESA_screen_surface
= EGL_TRUE
;
225 disp
->Extensions
.MESA_copy_context
= EGL_TRUE
;
240 drm_terminate(_EGLDriver
*drv
, _EGLDisplay
*dpy
)
242 struct drm_device
*dev
= lookup_drm_device(dpy
);
243 struct drm_screen
*screen
;
246 _eglReleaseDisplayResources(drv
, dpy
);
247 _eglCleanupDisplay(dpy
);
249 drmFreeVersion(dev
->version
);
251 for (i
= 0; i
< dev
->count_screens
; i
++) {
252 screen
= dev
->screens
[i
];
255 drm_takedown_shown_screen(dpy
, screen
);
257 drmModeFreeProperty(screen
->dpms
);
258 drmModeFreeConnector(screen
->connector
);
259 _eglDestroyScreen(&screen
->base
);
260 dev
->screens
[i
] = NULL
;
263 dev
->screen
->destroy(dev
->screen
);
266 drmClose(dev
->drmFD
);
268 dev
->api
->destroy(dev
->api
);
270 dpy
->DriverData
= NULL
;