7 #include "egl_tracker.h"
10 #include "state_tracker/drm_api.h"
12 #include "pipe/p_screen.h"
13 #include "pipe/internal/p_winsys_screen.h"
17 extern const struct dri_extension card_extensions
[];
25 * The bootstrap function. Return a new drm_driver object and
26 * plug in API functions.
29 _eglMain(_EGLDisplay
*dpy
, const char *args
)
31 struct drm_device
*drm
;
33 drm
= (struct drm_device
*) calloc(1, sizeof(struct drm_device
));
38 drm
->api
= drm_api_create();
40 /* First fill in the dispatch table with defaults */
41 _eglInitDriverFallbacks(&drm
->base
);
42 /* then plug in our Drm-specific functions */
43 drm
->base
.API
.Initialize
= drm_initialize
;
44 drm
->base
.API
.Terminate
= drm_terminate
;
45 drm
->base
.API
.CreateContext
= drm_create_context
;
46 drm
->base
.API
.MakeCurrent
= drm_make_current
;
47 drm
->base
.API
.CreateWindowSurface
= drm_create_window_surface
;
48 drm
->base
.API
.CreatePixmapSurface
= drm_create_pixmap_surface
;
49 drm
->base
.API
.CreatePbufferSurface
= drm_create_pbuffer_surface
;
50 drm
->base
.API
.DestroySurface
= drm_destroy_surface
;
51 drm
->base
.API
.DestroyContext
= drm_destroy_context
;
52 drm
->base
.API
.CreateScreenSurfaceMESA
= drm_create_screen_surface_mesa
;
53 drm
->base
.API
.ShowScreenSurfaceMESA
= drm_show_screen_surface_mesa
;
54 drm
->base
.API
.SwapBuffers
= drm_swap_buffers
;
56 drm
->base
.ClientAPIsMask
= EGL_OPENGL_BIT
/*| EGL_OPENGL_ES_BIT*/;
57 drm
->base
.Name
= "DRM/Gallium/Win";
59 /* enable supported extensions */
60 drm
->base
.Extensions
.MESA_screen_surface
= EGL_TRUE
;
61 drm
->base
.Extensions
.MESA_copy_context
= EGL_TRUE
;
67 drm_get_device_id(struct drm_device
*device
)
73 /* TODO get the real minor */
78 snprintf(path
, sizeof(path
), "/sys/class/drm/card%d/device/device", minor
);
79 file
= fopen(path
, "r");
81 _eglLog(_EGL_WARNING
, "Could not retrive device ID\n");
85 ret
= fgets(path
, sizeof( path
), file
);
89 sscanf(path
, "%x", &device
->deviceID
);
94 drm_update_res(struct drm_device
*dev
)
96 drmModeFreeResources(dev
->res
);
97 dev
->res
= drmModeGetResources(dev
->drmFD
);
101 drm_add_modes_from_connector(_EGLScreen
*screen
, drmModeConnectorPtr connector
)
103 drmModeModeInfoPtr m
= NULL
;
106 for (i
= 0; i
< connector
->count_modes
; i
++) {
107 m
= &connector
->modes
[i
];
108 _eglAddNewMode(screen
, m
->hdisplay
, m
->vdisplay
, m
->vrefresh
, m
->name
);
113 drm_find_dpms(struct drm_device
*dev
, struct drm_screen
*screen
)
115 drmModeConnectorPtr c
= screen
->connector
;
116 drmModePropertyPtr p
;
119 for (i
= 0; i
< c
->count_props
; i
++) {
120 p
= drmModeGetProperty(dev
->drmFD
, c
->props
[i
]);
121 if (!strcmp(p
->name
, "DPMS"))
124 drmModeFreeProperty(p
);
132 drm_initialize(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLint
*major
, EGLint
*minor
)
134 struct drm_device
*dev
= (struct drm_device
*)drv
;
135 struct drm_screen
*screen
= NULL
;
136 drmModeConnectorPtr connector
= NULL
;
137 drmModeResPtr res
= NULL
;
138 unsigned count_connectors
= 0;
143 fd
= drmOpen("i915", NULL
);
148 drm_get_device_id(dev
);
150 dev
->screen
= dev
->api
->create_screen(dev
->api
, dev
->drmFD
, NULL
);
153 dev
->winsys
= dev
->screen
->winsys
;
156 driInitExtensions(NULL
, card_extensions
, GL_FALSE
);
161 count_connectors
= res
->count_connectors
;
163 _eglLog(_EGL_WARNING
, "Could not retrive kms information\n");
165 for(i
= 0; i
< count_connectors
&& i
< MAX_SCREENS
; i
++) {
166 connector
= drmModeGetConnector(fd
, res
->connectors
[i
]);
171 if (connector
->connection
!= DRM_MODE_CONNECTED
) {
172 drmModeFreeConnector(connector
);
176 screen
= malloc(sizeof(struct drm_screen
));
177 memset(screen
, 0, sizeof(*screen
));
178 screen
->connector
= connector
;
179 screen
->connectorID
= connector
->connector_id
;
180 _eglInitScreen(&screen
->base
);
181 _eglAddScreen(disp
, &screen
->base
);
182 drm_add_modes_from_connector(&screen
->base
, connector
);
183 drm_find_dpms(dev
, screen
);
184 dev
->screens
[num_screens
++] = screen
;
186 dev
->count_screens
= num_screens
;
188 /* for now we only have one config */
189 _EGLConfig
*config
= calloc(1, sizeof(*config
));
190 memset(config
, 1, sizeof(*config
));
191 _eglInitConfig(config
, 1);
192 _eglSetConfigAttrib(config
, EGL_RED_SIZE
, 8);
193 _eglSetConfigAttrib(config
, EGL_GREEN_SIZE
, 8);
194 _eglSetConfigAttrib(config
, EGL_BLUE_SIZE
, 8);
195 _eglSetConfigAttrib(config
, EGL_ALPHA_SIZE
, 8);
196 _eglSetConfigAttrib(config
, EGL_BUFFER_SIZE
, 32);
197 _eglSetConfigAttrib(config
, EGL_DEPTH_SIZE
, 24);
198 _eglSetConfigAttrib(config
, EGL_STENCIL_SIZE
, 8);
199 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_PBUFFER_BIT
);
200 _eglAddConfig(disp
, config
);
202 drv
->Initialized
= EGL_TRUE
;
216 drm_terminate(_EGLDriver
*drv
, _EGLDisplay
*dpy
)
218 struct drm_device
*dev
= (struct drm_device
*)drv
;
219 struct drm_screen
*screen
;
222 drmFreeVersion(dev
->version
);
224 for (i
= 0; i
< dev
->count_screens
; i
++) {
225 screen
= dev
->screens
[i
];
228 drm_takedown_shown_screen(drv
, screen
);
230 drmModeFreeProperty(screen
->dpms
);
231 drmModeFreeConnector(screen
->connector
);
232 _eglDestroyScreen(&screen
->base
);
233 dev
->screens
[i
] = NULL
;
236 dev
->screen
->destroy(dev
->screen
);
238 dev
->api
->destroy(dev
->api
);
240 drmClose(dev
->drmFD
);
242 _eglCleanupDisplay(dpy
);