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 dpy
, EGLint
*major
, EGLint
*minor
)
134 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
135 struct drm_device
*dev
= (struct drm_device
*)drv
;
136 struct drm_screen
*screen
= NULL
;
137 drmModeConnectorPtr connector
= NULL
;
138 drmModeResPtr res
= NULL
;
139 unsigned count_connectors
= 0;
144 fd
= drmOpen("i915", NULL
);
149 drm_get_device_id(dev
);
151 dev
->screen
= dev
->api
->create_screen(dev
->api
, dev
->drmFD
, NULL
);
154 dev
->winsys
= dev
->screen
->winsys
;
157 driInitExtensions(NULL
, card_extensions
, GL_FALSE
);
162 count_connectors
= res
->count_connectors
;
164 _eglLog(_EGL_WARNING
, "Could not retrive kms information\n");
166 for(i
= 0; i
< count_connectors
&& i
< MAX_SCREENS
; i
++) {
167 connector
= drmModeGetConnector(fd
, res
->connectors
[i
]);
172 if (connector
->connection
!= DRM_MODE_CONNECTED
) {
173 drmModeFreeConnector(connector
);
177 screen
= malloc(sizeof(struct drm_screen
));
178 memset(screen
, 0, sizeof(*screen
));
179 screen
->connector
= connector
;
180 screen
->connectorID
= connector
->connector_id
;
181 _eglInitScreen(&screen
->base
);
182 _eglAddScreen(disp
, &screen
->base
);
183 drm_add_modes_from_connector(&screen
->base
, connector
);
184 drm_find_dpms(dev
, screen
);
185 dev
->screens
[num_screens
++] = screen
;
187 dev
->count_screens
= num_screens
;
189 /* for now we only have one config */
190 _EGLConfig
*config
= calloc(1, sizeof(*config
));
191 memset(config
, 1, sizeof(*config
));
192 _eglInitConfig(config
, 1);
193 _eglSetConfigAttrib(config
, EGL_RED_SIZE
, 8);
194 _eglSetConfigAttrib(config
, EGL_GREEN_SIZE
, 8);
195 _eglSetConfigAttrib(config
, EGL_BLUE_SIZE
, 8);
196 _eglSetConfigAttrib(config
, EGL_ALPHA_SIZE
, 8);
197 _eglSetConfigAttrib(config
, EGL_BUFFER_SIZE
, 32);
198 _eglSetConfigAttrib(config
, EGL_DEPTH_SIZE
, 24);
199 _eglSetConfigAttrib(config
, EGL_STENCIL_SIZE
, 8);
200 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_PBUFFER_BIT
);
201 _eglAddConfig(disp
, config
);
203 drv
->Initialized
= EGL_TRUE
;
217 drm_terminate(_EGLDriver
*drv
, EGLDisplay dpy
)
219 struct drm_device
*dev
= (struct drm_device
*)drv
;
220 struct drm_screen
*screen
;
223 drmFreeVersion(dev
->version
);
225 for (i
= 0; i
< dev
->count_screens
; i
++) {
226 screen
= dev
->screens
[i
];
229 drm_takedown_shown_screen(drv
, screen
);
231 drmModeFreeProperty(screen
->dpms
);
232 drmModeFreeConnector(screen
->connector
);
233 _eglDestroyScreen(&screen
->base
);
234 dev
->screens
[i
] = NULL
;
237 dev
->screen
->destroy(dev
->screen
);
239 dev
->api
->destroy(dev
->api
);
241 drmClose(dev
->drmFD
);
243 _eglCleanupDisplay(_eglLookupDisplay(dpy
));