From 7047f1755f88d6b1f424904e692edbd03a9d190b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 18 Jan 2009 15:36:47 +0100 Subject: egl: Add a egl state_tracker that use Gallium This works on top Gallium and KMS. The only thing that does not work currently is swap buffers for shown mesa screens. So the only fun thing this will produce is a white screen. The driver wishing to us the state_tracker needs to implement the intrace as define in drm_api.h located in gallium/include/state_tracker. And also have a working KMS implementation. --- src/gallium/state_trackers/egl/egl_tracker.h | 185 +++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/gallium/state_trackers/egl/egl_tracker.h (limited to 'src/gallium/state_trackers/egl/egl_tracker.h') diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h new file mode 100644 index 0000000000..df637a5343 --- /dev/null +++ b/src/gallium/state_trackers/egl/egl_tracker.h @@ -0,0 +1,185 @@ + +#ifndef _EGL_TRACKER_H_ +#define _EGL_TRACKER_H_ + +#include + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "eglmode.h" +#include "eglscreen.h" +#include "eglsurface.h" + +#include "xf86drm.h" +#include "xf86drmMode.h" + +#include "pipe/p_compiler.h" + +#include "state_tracker/st_public.h" + +#define MAX_SCREENS 16 + +struct pipe_winsys; +struct pipe_screen; +struct pipe_context; +struct state_tracker; + +struct drm_screen; +struct drm_context; + +struct drm_device +{ + _EGLDriver base; /* base class/object */ + + /* + * pipe + */ + + struct pipe_winsys *winsys; + struct pipe_screen *screen; + + /* + * drm + */ + + int drmFD; + drmVersionPtr version; + int deviceID; + + drmModeResPtr res; + + struct drm_screen *screens[MAX_SCREENS]; + size_t count_screens; +}; + +struct drm_surface +{ + _EGLSurface base; /* base class/object */ + + /* + * pipe + */ + + + struct st_framebuffer *stfb; + + /* + * drm + */ + + struct drm_context *user; + struct drm_screen *screen; + + int w; + int h; +}; + +struct drm_context +{ + _EGLContext base; /* base class/object */ + + /* pipe */ + + struct pipe_context *pipe; + struct st_context *st; +}; + +struct drm_screen +{ + _EGLScreen base; + + /* + * pipe + */ + + struct pipe_buffer *buffer; + + /* + * drm + */ + + /* buffer handle */ + int handle; + + /* currently only support one connector */ + drmModeConnectorPtr connector; + uint32_t connectorID; + + /* Has this screen been shown */ + int shown; + + /* Surface that is currently attached to this screen */ + struct drm_surface *surf; + + /* framebuffer */ + drmModeFBPtr fb; + uint32_t fbID; + + /* crtc and mode used */ + /*drmModeCrtcPtr crtc;*/ + uint32_t crtcID; + + struct drm_mode_modeinfo *mode; +}; + + +static INLINE struct drm_context * +lookup_drm_context(EGLContext context) +{ + _EGLContext *c = _eglLookupContext(context); + return (struct drm_context *) c; +} + + +static INLINE struct drm_surface * +lookup_drm_surface(EGLSurface surface) +{ + _EGLSurface *s = _eglLookupSurface(surface); + return (struct drm_surface *) s; +} + +static INLINE struct drm_screen * +lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) +{ + _EGLScreen *s = _eglLookupScreen(dpy, screen); + return (struct drm_screen *) s; +} + +/** + * egl_visual.h + */ +/*@{*/ +void drm_visual_modes_destroy(__GLcontextModes *modes); +__GLcontextModes* drm_visual_modes_create(unsigned count, size_t minimum_size); +__GLcontextModes* drm_visual_from_config(_EGLConfig *conf); +/*@}*/ + +/** + * egl_surface.h + */ +/*@{*/ +void drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen); +/*@}*/ + +/** + * All function exported to the egl side. + */ +/*@{*/ +EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor); +EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy); +EGLContext drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list); +EGLBoolean drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context); +EGLSurface drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list); +EGLSurface drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list); +EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +EGLSurface drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, const EGLint *attrib_list); +EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA m); +EGLBoolean drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface); +EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context); +EGLBoolean drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw); +/*@}*/ + +#endif -- cgit v1.2.3 From e082923af66a2b4c3fa7b3f104930addd8d6ac5b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 19 Jan 2009 02:00:35 +0100 Subject: egl: Fix swap and creation of front buffer --- src/gallium/state_trackers/egl/egl_surface.c | 130 +++++++++++++++++++++++---- src/gallium/state_trackers/egl/egl_tracker.h | 10 ++- 2 files changed, 120 insertions(+), 20 deletions(-) (limited to 'src/gallium/state_trackers/egl/egl_tracker.h') diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c index 1bd3a91d57..71292bf2a9 100644 --- a/src/gallium/state_trackers/egl/egl_surface.c +++ b/src/gallium/state_trackers/egl/egl_surface.c @@ -7,6 +7,8 @@ #include "egllog.h" #include "pipe/p_inlines.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" #include "state_tracker/drm_api.h" @@ -64,6 +66,97 @@ drm_create_framebuffer(const __GLcontextModes *visual, priv); } +static void +drm_create_texture(_EGLDriver *drv, + struct drm_screen *scrn, + unsigned w, unsigned h) +{ + struct drm_device *dev = (struct drm_device *)drv; + struct pipe_screen *screen = dev->screen; + struct pipe_surface *surface; + struct pipe_texture *texture; + struct pipe_texture templat; + struct pipe_buffer *buf; + unsigned stride = 1024; + unsigned pitch = 0; + unsigned size = 0; + void *ptr; + + /* ugly */ + if (stride < w) + stride = 2048; + + pitch = stride * 4; + size = h * 2 * pitch; + + buf = pipe_buffer_create(screen, + 0, /* alignment */ + PIPE_BUFFER_USAGE_GPU_READ_WRITE | + PIPE_BUFFER_USAGE_CPU_READ_WRITE, + size); + + if (!buf) + goto err_buf; + +#if DEBUG + ptr = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE); + memset(ptr, 0xFF, size); + pipe_buffer_unmap(screen, buf); +#else + (void)ptr; +#endif + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.width[0] = w; + templat.height[0] = h; + pf_get_block(templat.format, &templat.block); + + texture = screen->texture_blanket(dev->screen, + &templat, + &pitch, + buf); + if (!texture) + goto err_tex; + + surface = screen->get_tex_surface(screen, + texture, + 0, + 0, + 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + if (!surface) + goto err_surf; + + + scrn->tex = texture; + scrn->surface = surface; + scrn->buffer = buf; + scrn->front.width = w; + scrn->front.height = h; + scrn->front.pitch = pitch; + scrn->front.handle = drm_api_hocks.handle_from_buffer(dev->winsys, scrn->buffer); + if (0) + goto err_handle; + + return; + +err_handle: + pipe_surface_reference(&surface, NULL); +err_surf: + pipe_texture_reference(&texture, NULL); +err_tex: + pipe_buffer_reference(screen, &buf, NULL); +err_buf: + return; +} + /* * Exported functions */ @@ -87,6 +180,8 @@ drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) drmModeFreeFB(screen->fb); screen->fb = NULL; + pipe_surface_reference(&screen->surface, NULL); + pipe_texture_reference(&screen->tex, NULL); pipe_buffer_reference(dev->screen, &screen->buffer, NULL); screen->shown = 0; @@ -186,33 +281,21 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, struct drm_surface *surf = lookup_drm_surface(surface); struct drm_screen *scrn = lookup_drm_screen(dpy, screen); _EGLMode *mode = _eglLookupMode(dpy, m); - size_t pitch = 2048 * 4; - size_t size = mode->Height * pitch; int ret; unsigned int i, k; - void *ptr; if (scrn->shown) drm_takedown_shown_screen(drv, scrn); - scrn->buffer = pipe_buffer_create(dev->screen, - 0, /* alignment */ - PIPE_BUFFER_USAGE_GPU_READ_WRITE | - PIPE_BUFFER_USAGE_CPU_READ_WRITE, - size); + drm_create_texture(drv, scrn, mode->Width, mode->Height); if (!scrn->buffer) return EGL_FALSE; - ptr = pipe_buffer_map(dev->screen, scrn->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - memset(ptr, 0xFF, size); - pipe_buffer_unmap(dev->screen, scrn->buffer); - - scrn->handle = drm_api_hocks.handle_from_buffer(dev->winsys, scrn->buffer); - - ret = drmModeAddFB(dev->drmFD, mode->Width, mode->Height, - 32, 32, pitch, - scrn->handle, + ret = drmModeAddFB(dev->drmFD, + scrn->front.width, scrn->front.height, + 32, 32, scrn->front.pitch, + scrn->front.handle, &scrn->fbID); if (ret) @@ -257,8 +340,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, goto err_crtc; surf->screen = scrn; - scrn->surf = surf; + scrn->surf = surf; scrn->shown = 1; return EGL_TRUE; @@ -272,6 +355,8 @@ err_fb: scrn->fb = NULL; err_bo: + pipe_surface_reference(&scrn->surface, NULL); + pipe_texture_reference(&scrn->tex, NULL); pipe_buffer_reference(dev->screen, &scrn->buffer, NULL); return EGL_FALSE; @@ -314,6 +399,15 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) st_notify_swapbuffers(surf->stfb); if (surf->screen) { + surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL); + surf->user->pipe->surface_copy(surf->user->pipe, + 0, + surf->screen->surface, + 0, 0, + back_surf, + 0, 0, + surf->w, surf->h); + surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL); /* TODO stuff here */ } diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h index df637a5343..0b4dd9797d 100644 --- a/src/gallium/state_trackers/egl/egl_tracker.h +++ b/src/gallium/state_trackers/egl/egl_tracker.h @@ -96,13 +96,19 @@ struct drm_screen */ struct pipe_buffer *buffer; + struct pipe_texture *tex; + struct pipe_surface *surface; /* * drm */ - /* buffer handle */ - int handle; + struct { + unsigned height; + unsigned width; + unsigned pitch; + unsigned handle; + } front; /* currently only support one connector */ drmModeConnectorPtr connector; -- cgit v1.2.3