5 #include "egl_tracker.h"
9 #include "pipe/p_inlines.h"
10 #include "pipe/p_screen.h"
11 #include "pipe/p_context.h"
13 #include "state_tracker/drm_api.h"
19 static drmModeModeInfoPtr
20 drm_find_mode(drmModeConnectorPtr connector
, _EGLMode
*mode
)
23 drmModeModeInfoPtr m
= NULL
;
25 for (i
= 0; i
< connector
->count_modes
; i
++) {
26 m
= &connector
->modes
[i
];
27 if (m
->hdisplay
== mode
->Width
&& m
->vdisplay
== mode
->Height
&& m
->vrefresh
== mode
->RefreshRate
)
29 m
= &connector
->modes
[0]; /* if we can't find one, return first */
35 static struct st_framebuffer
*
36 drm_create_framebuffer(const __GLcontextModes
*visual
,
41 enum pipe_format colorFormat
, depthFormat
, stencilFormat
;
43 if (visual
->redBits
== 5)
44 colorFormat
= PIPE_FORMAT_R5G6B5_UNORM
;
46 colorFormat
= PIPE_FORMAT_A8R8G8B8_UNORM
;
48 if (visual
->depthBits
== 16)
49 depthFormat
= PIPE_FORMAT_Z16_UNORM
;
50 else if (visual
->depthBits
== 24)
51 depthFormat
= PIPE_FORMAT_S8Z24_UNORM
;
53 depthFormat
= PIPE_FORMAT_NONE
;
55 if (visual
->stencilBits
== 8)
56 stencilFormat
= PIPE_FORMAT_S8Z24_UNORM
;
58 stencilFormat
= PIPE_FORMAT_NONE
;
60 return st_create_framebuffer(visual
,
70 drm_create_texture(_EGLDriver
*drv
,
71 struct drm_screen
*scrn
,
72 unsigned w
, unsigned h
)
74 struct drm_device
*dev
= (struct drm_device
*)drv
;
75 struct pipe_screen
*screen
= dev
->screen
;
76 struct pipe_surface
*surface
;
77 struct pipe_texture
*texture
;
78 struct pipe_texture templat
;
79 struct pipe_buffer
*buf
;
80 unsigned stride
= 1024;
91 buf
= pipe_buffer_create(screen
,
93 PIPE_BUFFER_USAGE_GPU_READ_WRITE
|
94 PIPE_BUFFER_USAGE_CPU_READ_WRITE
,
100 memset(&templat
, 0, sizeof(templat
));
101 templat
.tex_usage
|= PIPE_TEXTURE_USAGE_DISPLAY_TARGET
;
102 templat
.tex_usage
|= PIPE_TEXTURE_USAGE_RENDER_TARGET
;
103 templat
.target
= PIPE_TEXTURE_2D
;
104 templat
.last_level
= 0;
105 templat
.depth
[0] = 1;
106 templat
.format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
107 templat
.width
[0] = w
;
108 templat
.height
[0] = h
;
109 pf_get_block(templat
.format
, &templat
.block
);
111 texture
= screen
->texture_blanket(dev
->screen
,
118 surface
= screen
->get_tex_surface(screen
,
123 PIPE_BUFFER_USAGE_GPU_WRITE
);
130 scrn
->surface
= surface
;
132 scrn
->front
.width
= w
;
133 scrn
->front
.height
= h
;
134 scrn
->front
.pitch
= pitch
;
135 drm_api_hooks
.handle_from_buffer(screen
, scrn
->buffer
, &scrn
->front
.handle
);
142 pipe_surface_reference(&surface
, NULL
);
144 pipe_texture_reference(&texture
, NULL
);
146 pipe_buffer_reference(&buf
, NULL
);
156 drm_takedown_shown_screen(_EGLDriver
*drv
, struct drm_screen
*screen
)
158 struct drm_device
*dev
= (struct drm_device
*)drv
;
167 NULL
, 0, // List of output ids
170 drmModeRmFB(dev
->drmFD
, screen
->fbID
);
171 drmModeFreeFB(screen
->fb
);
174 pipe_surface_reference(&screen
->surface
, NULL
);
175 pipe_texture_reference(&screen
->tex
, NULL
);
176 pipe_buffer_reference(&screen
->buffer
, NULL
);
182 drm_create_window_surface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
, NativeWindowType window
, const EGLint
*attrib_list
)
184 return EGL_NO_SURFACE
;
189 drm_create_pixmap_surface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
, NativePixmapType pixmap
, const EGLint
*attrib_list
)
191 return EGL_NO_SURFACE
;
196 drm_create_pbuffer_surface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
197 const EGLint
*attrib_list
)
202 struct drm_surface
*surf
= NULL
;
203 __GLcontextModes
*visual
;
206 conf
= _eglLookupConfig(drv
, dpy
, config
);
208 _eglError(EGL_BAD_CONFIG
, "eglCreatePbufferSurface");
209 return EGL_NO_CONTEXT
;
212 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
213 switch (attrib_list
[i
]) {
215 width
= attrib_list
[++i
];
218 height
= attrib_list
[++i
];
221 _eglError(EGL_BAD_ATTRIBUTE
, "eglCreatePbufferSurface");
222 return EGL_NO_SURFACE
;
226 if (width
< 1 || height
< 1) {
227 _eglError(EGL_BAD_ATTRIBUTE
, "eglCreatePbufferSurface");
228 return EGL_NO_SURFACE
;
231 surf
= (struct drm_surface
*) calloc(1, sizeof(struct drm_surface
));
235 if (!_eglInitSurface(drv
, dpy
, &surf
->base
, EGL_PBUFFER_BIT
, config
, attrib_list
))
241 visual
= drm_visual_from_config(conf
);
242 surf
->stfb
= drm_create_framebuffer(visual
,
246 drm_visual_modes_destroy(visual
);
248 _eglSaveSurface(&surf
->base
);
249 return surf
->base
.Handle
;
254 return EGL_NO_SURFACE
;
258 drm_create_screen_surface_mesa(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig cfg
,
259 const EGLint
*attrib_list
)
261 EGLSurface surf
= drm_create_pbuffer_surface(drv
, dpy
, cfg
, attrib_list
);
267 drm_show_screen_surface_mesa(_EGLDriver
*drv
, EGLDisplay dpy
,
268 EGLScreenMESA screen
,
269 EGLSurface surface
, EGLModeMESA m
)
271 struct drm_device
*dev
= (struct drm_device
*)drv
;
272 struct drm_surface
*surf
= lookup_drm_surface(surface
);
273 struct drm_screen
*scrn
= lookup_drm_screen(dpy
, screen
);
274 _EGLMode
*mode
= _eglLookupMode(dpy
, m
);
279 drm_takedown_shown_screen(drv
, scrn
);
282 drm_create_texture(drv
, scrn
, mode
->Width
, mode
->Height
);
286 ret
= drmModeAddFB(dev
->drmFD
,
287 scrn
->front
.width
, scrn
->front
.height
,
288 32, 32, scrn
->front
.pitch
,
295 scrn
->fb
= drmModeGetFB(dev
->drmFD
, scrn
->fbID
);
299 /* find a fitting crtc */
301 drmModeConnector
*con
= scrn
->connector
;
303 scrn
->mode
= drm_find_mode(con
, mode
);
307 for (k
= 0; k
< con
->count_encoders
; k
++) {
308 drmModeEncoder
*enc
= drmModeGetEncoder(dev
->drmFD
, con
->encoders
[k
]);
309 for (i
= 0; i
< dev
->res
->count_crtcs
; i
++) {
310 if (enc
->possible_crtcs
& (1<<i
)) {
312 scrn
->crtcID
= dev
->res
->crtcs
[i
];
315 i
= dev
->res
->count_crtcs
;
316 k
= dev
->res
->count_encoders
;
319 drmModeFreeEncoder(enc
);
323 ret
= drmModeSetCrtc(dev
->drmFD
,
327 &scrn
->connectorID
, 1,
344 drmModeRmFB(dev
->drmFD
, scrn
->fbID
);
345 drmModeFreeFB(scrn
->fb
);
349 pipe_surface_reference(&scrn
->surface
, NULL
);
350 pipe_texture_reference(&scrn
->tex
, NULL
);
351 pipe_buffer_reference(&scrn
->buffer
, NULL
);
357 drm_destroy_surface(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface surface
)
359 struct drm_surface
*surf
= lookup_drm_surface(surface
);
360 _eglRemoveSurface(&surf
->base
);
361 if (surf
->base
.IsBound
) {
362 surf
->base
.DeletePending
= EGL_TRUE
;
365 drm_takedown_shown_screen(drv
, surf
->screen
);
366 st_unreference_framebuffer(surf
->stfb
);
373 drm_swap_buffers(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface draw
)
375 struct drm_surface
*surf
= lookup_drm_surface(draw
);
376 struct pipe_surface
*back_surf
;
382 if (!_eglSwapBuffers(drv
, dpy
, draw
))
385 st_get_framebuffer_surface(surf
->stfb
, ST_SURFACE_BACK_LEFT
, &back_surf
);
389 st_notify_swapbuffers(surf
->stfb
);
392 surf
->user
->pipe
->flush(surf
->user
->pipe
, PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_TEXTURE_CACHE
, NULL
);
393 surf
->user
->pipe
->surface_copy(surf
->user
->pipe
,
394 surf
->screen
->surface
,
399 surf
->user
->pipe
->flush(surf
->user
->pipe
, PIPE_FLUSH_RENDER_CACHE
| PIPE_FLUSH_TEXTURE_CACHE
, NULL
);
400 /* TODO stuff here */
403 st_notify_swapbuffers_complete(surf
->stfb
);