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;
157 dev
= (struct drm_device
*) calloc(1, sizeof(struct drm_device
));
160 dev
->api
= drm_api_create();
162 /* try the first node */
163 fd
= drm_open_minor(0);
168 drm_get_device_id(dev
);
170 dev
->screen
= dev
->api
->create_screen(dev
->api
, dev
->drmFD
, NULL
);
173 dev
->winsys
= dev
->screen
->winsys
;
178 count_connectors
= res
->count_connectors
;
180 _eglLog(_EGL_WARNING
, "Could not retrive kms information\n");
182 for(i
= 0; i
< count_connectors
&& i
< MAX_SCREENS
; i
++) {
183 connector
= drmModeGetConnector(fd
, res
->connectors
[i
]);
188 if (connector
->connection
!= DRM_MODE_CONNECTED
) {
189 drmModeFreeConnector(connector
);
193 screen
= malloc(sizeof(struct drm_screen
));
194 memset(screen
, 0, sizeof(*screen
));
195 screen
->connector
= connector
;
196 screen
->connectorID
= connector
->connector_id
;
197 _eglInitScreen(&screen
->base
);
198 _eglAddScreen(disp
, &screen
->base
);
199 drm_add_modes_from_connector(&screen
->base
, connector
);
200 drm_find_dpms(dev
, screen
);
201 dev
->screens
[num_screens
++] = screen
;
203 dev
->count_screens
= num_screens
;
205 disp
->DriverData
= dev
;
207 /* for now we only have one config */
208 config
= calloc(1, sizeof(*config
));
209 memset(config
, 1, sizeof(*config
));
210 _eglInitConfig(config
, 1);
211 _eglSetConfigAttrib(config
, EGL_RED_SIZE
, 8);
212 _eglSetConfigAttrib(config
, EGL_GREEN_SIZE
, 8);
213 _eglSetConfigAttrib(config
, EGL_BLUE_SIZE
, 8);
214 _eglSetConfigAttrib(config
, EGL_ALPHA_SIZE
, 8);
215 _eglSetConfigAttrib(config
, EGL_BUFFER_SIZE
, 32);
216 _eglSetConfigAttrib(config
, EGL_DEPTH_SIZE
, 24);
217 _eglSetConfigAttrib(config
, EGL_STENCIL_SIZE
, 8);
218 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_PBUFFER_BIT
);
219 _eglAddConfig(disp
, config
);
221 disp
->ClientAPIsMask
= EGL_OPENGL_BIT
/*| EGL_OPENGL_ES_BIT*/;
222 /* enable supported extensions */
223 disp
->Extensions
.MESA_screen_surface
= EGL_TRUE
;
224 disp
->Extensions
.MESA_copy_context
= EGL_TRUE
;
239 drm_terminate(_EGLDriver
*drv
, _EGLDisplay
*dpy
)
241 struct drm_device
*dev
= lookup_drm_device(dpy
);
242 struct drm_screen
*screen
;
245 _eglReleaseDisplayResources(drv
, dpy
);
246 _eglCleanupDisplay(dpy
);
248 drmFreeVersion(dev
->version
);
250 for (i
= 0; i
< dev
->count_screens
; i
++) {
251 screen
= dev
->screens
[i
];
254 drm_takedown_shown_screen(dpy
, screen
);
256 drmModeFreeProperty(screen
->dpms
);
257 drmModeFreeConnector(screen
->connector
);
258 _eglDestroyScreen(&screen
->base
);
259 dev
->screens
[i
] = NULL
;
262 dev
->screen
->destroy(dev
->screen
);
265 drmClose(dev
->drmFD
);
267 dev
->api
->destroy(dev
->api
);
269 dpy
->DriverData
= NULL
;