The egl_g3d state tracker has support for KMS, and the support is based on the egl state tracker. As egl_g3d provides more features, it should be better to keep only egl_g3d to unify the efforts.tags/7.8-rc1
@@ -61,7 +61,7 @@ DRIVER_DIRS = dri | |||
WINDOW_SYSTEM = dri | |||
GALLIUM_WINSYS_DIRS = drm | |||
GALLIUM_WINSYS_DRM_DIRS = vmware intel i965 | |||
GALLIUM_STATE_TRACKERS_DIRS = egl | |||
GALLIUM_STATE_TRACKERS_DIRS = egl_g3d | |||
DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon \ | |||
savage sis tdfx unichrome ffb swrast |
@@ -9,6 +9,9 @@ LIB_DIR = lib | |||
SRC_DIRS = egl glsl mesa/es gallium gallium/winsys | |||
PROGRAM_DIRS = es1/screen es1/xegl es2/xegl | |||
# egl_g3d needs this | |||
DEFINES += -DGLX_DIRECT_RENDERING | |||
# no mesa or egl drivers | |||
DRIVER_DIRS = | |||
EGL_DRIVERS_DIRS = | |||
@@ -22,6 +25,6 @@ GALLIUM_STATE_TRACKERS_DIRS = es | |||
# build egl_i915.so | |||
GALLIUM_DRIVERS_DIRS += trace i915 | |||
GALLIUM_STATE_TRACKERS_DIRS += egl | |||
GALLIUM_STATE_TRACKERS_DIRS += egl_g3d | |||
GALLIUM_WINSYS_DIRS += drm | |||
GALLIUM_WINSYS_DRM_DIRS = intel |
@@ -1165,7 +1165,7 @@ yes) | |||
dri) | |||
GALLIUM_STATE_TRACKERS_DIRS="dri" | |||
if test "x$enable_egl" = xyes; then | |||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl egl_g3d" | |||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl_g3d" | |||
fi | |||
# Have only tested st/xorg on 1.6.0 servers | |||
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0], | |||
@@ -1182,9 +1182,9 @@ yes) | |||
AC_MSG_ERROR([state tracker '$tracker' doesn't exist]) | |||
case "$tracker" in | |||
egl) | |||
egl_g3d) | |||
if test "x$enable_egl" != xyes; then | |||
AC_MSG_ERROR([cannot build egl state tracker without EGL library]) | |||
AC_MSG_ERROR([cannot build egl_g3d state tracker without EGL library]) | |||
fi | |||
;; | |||
xorg) |
@@ -1,19 +0,0 @@ | |||
TOP = ../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = egldrm | |||
LIBRARY_INCLUDES = \ | |||
-I$(TOP)/src/gallium/include \ | |||
-I$(TOP)/src/gallium/auxiliary \ | |||
-I$(TOP)/src/mesa/drivers/dri/common \ | |||
-I$(TOP)/src/mesa \ | |||
-I$(TOP)/include \ | |||
-I$(TOP)/src/egl/main \ | |||
$(shell pkg-config --cflags-only-I libdrm) | |||
C_SOURCES = $(wildcard ./*.c) | |||
include ../../Makefile.template |
@@ -1,105 +0,0 @@ | |||
#include "utils.h" | |||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include "egl_tracker.h" | |||
#include "egllog.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_screen.h" | |||
#include "state_tracker/st_public.h" | |||
#include "state_tracker/drm_api.h" | |||
#include "GL/internal/glcore.h" | |||
_EGLContext * | |||
drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) | |||
{ | |||
struct drm_device *dev = lookup_drm_device(dpy); | |||
struct drm_context *ctx; | |||
struct drm_context *share = NULL; | |||
struct st_context *st_share = NULL; | |||
int i; | |||
__GLcontextModes *visual; | |||
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { | |||
switch (attrib_list[i]) { | |||
/* no attribs defined for now */ | |||
default: | |||
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); | |||
return EGL_NO_CONTEXT; | |||
} | |||
} | |||
ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context)); | |||
if (!ctx) | |||
goto err_c; | |||
_eglInitContext(drv, &ctx->base, conf, attrib_list); | |||
ctx->pipe = dev->api->create_context(dev->api, dev->screen); | |||
if (!ctx->pipe) | |||
goto err_pipe; | |||
if (share) | |||
st_share = share->st; | |||
visual = drm_visual_from_config(conf); | |||
ctx->st = st_create_context(ctx->pipe, visual, st_share); | |||
drm_visual_modes_destroy(visual); | |||
if (!ctx->st) | |||
goto err_gl; | |||
return &ctx->base; | |||
err_gl: | |||
ctx->pipe->destroy(ctx->pipe); | |||
err_pipe: | |||
free(ctx); | |||
err_c: | |||
return NULL; | |||
} | |||
EGLBoolean | |||
drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context) | |||
{ | |||
struct drm_context *c = lookup_drm_context(context); | |||
if (!_eglIsContextBound(&c->base)) { | |||
st_destroy_context(c->st); | |||
free(c); | |||
} | |||
return EGL_TRUE; | |||
} | |||
EGLBoolean | |||
drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context) | |||
{ | |||
struct drm_surface *readSurf = lookup_drm_surface(read); | |||
struct drm_surface *drawSurf = lookup_drm_surface(draw); | |||
struct drm_context *ctx = lookup_drm_context(context); | |||
EGLBoolean b; | |||
b = _eglMakeCurrent(drv, dpy, draw, read, context); | |||
if (!b) | |||
return EGL_FALSE; | |||
if (ctx) { | |||
if (!drawSurf || !readSurf) | |||
return EGL_FALSE; | |||
st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb); | |||
/* st_resize_framebuffer needs a bound context to work */ | |||
st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h); | |||
st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h); | |||
} else { | |||
st_make_current(NULL, NULL, NULL); | |||
} | |||
return EGL_TRUE; | |||
} |
@@ -1,443 +0,0 @@ | |||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include "egl_tracker.h" | |||
#include "egllog.h" | |||
#include "pipe/p_inlines.h" | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_context.h" | |||
#include "state_tracker/drm_api.h" | |||
#include "util/u_format.h" | |||
#include "util/u_rect.h" | |||
/* | |||
* Util functions | |||
*/ | |||
static drmModeModeInfoPtr | |||
drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) | |||
{ | |||
int i; | |||
drmModeModeInfoPtr m = NULL; | |||
for (i = 0; i < connector->count_modes; i++) { | |||
m = &connector->modes[i]; | |||
if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) | |||
break; | |||
m = &connector->modes[0]; /* if we can't find one, return first */ | |||
} | |||
return m; | |||
} | |||
static struct st_framebuffer * | |||
drm_create_framebuffer(struct pipe_screen *screen, | |||
const __GLcontextModes *visual, | |||
unsigned width, | |||
unsigned height, | |||
void *priv) | |||
{ | |||
enum pipe_format color_format, depth_stencil_format; | |||
boolean d_depth_bits_last; | |||
boolean ds_depth_bits_last; | |||
d_depth_bits_last = | |||
screen->is_format_supported(screen, PIPE_FORMAT_X8Z24_UNORM, | |||
PIPE_TEXTURE_2D, | |||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||
ds_depth_bits_last = | |||
screen->is_format_supported(screen, PIPE_FORMAT_S8Z24_UNORM, | |||
PIPE_TEXTURE_2D, | |||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); | |||
if (visual->redBits == 8) { | |||
if (visual->alphaBits == 8) | |||
color_format = PIPE_FORMAT_A8R8G8B8_UNORM; | |||
else | |||
color_format = PIPE_FORMAT_X8R8G8B8_UNORM; | |||
} else { | |||
color_format = PIPE_FORMAT_R5G6B5_UNORM; | |||
} | |||
switch(visual->depthBits) { | |||
default: | |||
case 0: | |||
depth_stencil_format = PIPE_FORMAT_NONE; | |||
break; | |||
case 16: | |||
depth_stencil_format = PIPE_FORMAT_Z16_UNORM; | |||
break; | |||
case 24: | |||
if (visual->stencilBits == 0) { | |||
depth_stencil_format = (d_depth_bits_last) ? | |||
PIPE_FORMAT_X8Z24_UNORM: | |||
PIPE_FORMAT_Z24X8_UNORM; | |||
} else { | |||
depth_stencil_format = (ds_depth_bits_last) ? | |||
PIPE_FORMAT_S8Z24_UNORM: | |||
PIPE_FORMAT_Z24S8_UNORM; | |||
} | |||
break; | |||
case 32: | |||
depth_stencil_format = PIPE_FORMAT_Z32_UNORM; | |||
break; | |||
} | |||
return st_create_framebuffer(visual, | |||
color_format, | |||
depth_stencil_format, | |||
depth_stencil_format, | |||
width, | |||
height, | |||
priv); | |||
} | |||
static void | |||
drm_create_texture(_EGLDisplay *dpy, | |||
struct drm_screen *scrn, | |||
unsigned w, unsigned h) | |||
{ | |||
struct drm_device *dev = lookup_drm_device(dpy); | |||
struct pipe_screen *screen = dev->screen; | |||
struct pipe_surface *surface; | |||
struct pipe_texture *texture; | |||
struct pipe_texture templat; | |||
struct pipe_buffer *buf = NULL; | |||
unsigned pitch = 0; | |||
memset(&templat, 0, sizeof(templat)); | |||
templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; | |||
templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; | |||
templat.target = PIPE_TEXTURE_2D; | |||
templat.last_level = 0; | |||
templat.depth0 = 1; | |||
templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; | |||
templat.width0 = w; | |||
templat.height0 = h; | |||
texture = screen->texture_create(dev->screen, | |||
&templat); | |||
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->front.width = w; | |||
scrn->front.height = h; | |||
scrn->front.pitch = pitch; | |||
dev->api->local_handle_from_texture(dev->api, screen, texture, | |||
&scrn->front.pitch, &scrn->front.handle); | |||
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(&buf, NULL); | |||
return; | |||
} | |||
/* | |||
* Exported functions | |||
*/ | |||
void | |||
drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen) | |||
{ | |||
struct drm_device *dev = lookup_drm_device(dpy); | |||
screen->surf = NULL; | |||
drmModeSetCrtc( | |||
dev->drmFD, | |||
screen->crtcID, | |||
0, /* FD */ | |||
0, 0, | |||
NULL, 0, /* List of output ids */ | |||
NULL); | |||
drmModeRmFB(dev->drmFD, screen->fbID); | |||
drmModeFreeFB(screen->fb); | |||
screen->fb = NULL; | |||
pipe_surface_reference(&screen->surface, NULL); | |||
pipe_texture_reference(&screen->tex, NULL); | |||
screen->shown = 0; | |||
} | |||
/** | |||
* Called by libEGL's eglCreateWindowSurface(). | |||
*/ | |||
_EGLSurface * | |||
drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) | |||
{ | |||
return NULL; | |||
} | |||
/** | |||
* Called by libEGL's eglCreatePixmapSurface(). | |||
*/ | |||
_EGLSurface * | |||
drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) | |||
{ | |||
return NULL; | |||
} | |||
/** | |||
* Called by libEGL's eglCreatePbufferSurface(). | |||
*/ | |||
_EGLSurface * | |||
drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, | |||
const EGLint *attrib_list) | |||
{ | |||
struct drm_device *dev = lookup_drm_device(dpy); | |||
int i; | |||
int width = -1; | |||
int height = -1; | |||
struct drm_surface *surf = NULL; | |||
__GLcontextModes *visual; | |||
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { | |||
switch (attrib_list[i]) { | |||
case EGL_WIDTH: | |||
width = attrib_list[++i]; | |||
break; | |||
case EGL_HEIGHT: | |||
height = attrib_list[++i]; | |||
break; | |||
default: | |||
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); | |||
return EGL_NO_SURFACE; | |||
} | |||
} | |||
if (width < 1 || height < 1) { | |||
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); | |||
return NULL; | |||
} | |||
surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); | |||
if (!surf) | |||
goto err; | |||
if (!_eglInitSurface(drv, &surf->base, EGL_PBUFFER_BIT, conf, attrib_list)) | |||
goto err_surf; | |||
surf->w = width; | |||
surf->h = height; | |||
visual = drm_visual_from_config(conf); | |||
surf->stfb = drm_create_framebuffer(dev->screen, visual, | |||
width, height, | |||
(void*)surf); | |||
drm_visual_modes_destroy(visual); | |||
return &surf->base; | |||
err_surf: | |||
free(surf); | |||
err: | |||
return NULL; | |||
} | |||
/** | |||
* Called by libEGL's eglCreateScreenSurfaceMESA(). | |||
*/ | |||
_EGLSurface * | |||
drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg, | |||
const EGLint *attrib_list) | |||
{ | |||
EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); | |||
return surf; | |||
} | |||
/** | |||
* Called by libEGL's eglShowScreenSurfaceMESA(). | |||
*/ | |||
EGLBoolean | |||
drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, | |||
_EGLScreen *screen, | |||
_EGLSurface *surface, _EGLMode *mode) | |||
{ | |||
struct drm_device *dev = lookup_drm_device(dpy); | |||
struct drm_surface *surf = lookup_drm_surface(surface); | |||
struct drm_screen *scrn = lookup_drm_screen(screen); | |||
int ret; | |||
unsigned int i, k; | |||
if (scrn->shown) | |||
drm_takedown_shown_screen(dpy, scrn); | |||
drm_create_texture(dpy, scrn, mode->Width, mode->Height); | |||
if (!scrn->tex) | |||
goto err_tex; | |||
ret = drmModeAddFB(dev->drmFD, | |||
scrn->front.width, scrn->front.height, | |||
32, 32, scrn->front.pitch, | |||
scrn->front.handle, | |||
&scrn->fbID); | |||
if (ret) | |||
goto err_bo; | |||
scrn->fb = drmModeGetFB(dev->drmFD, scrn->fbID); | |||
if (!scrn->fb) | |||
goto err_bo; | |||
/* find a fitting crtc */ | |||
{ | |||
drmModeConnector *con = scrn->connector; | |||
scrn->mode = drm_find_mode(con, mode); | |||
if (!scrn->mode) | |||
goto err_fb; | |||
for (k = 0; k < con->count_encoders; k++) { | |||
drmModeEncoder *enc = drmModeGetEncoder(dev->drmFD, con->encoders[k]); | |||
for (i = 0; i < dev->res->count_crtcs; i++) { | |||
if (enc->possible_crtcs & (1<<i)) { | |||
/* save the ID */ | |||
scrn->crtcID = dev->res->crtcs[i]; | |||
/* skip the rest */ | |||
i = dev->res->count_crtcs; | |||
k = dev->res->count_encoders; | |||
} | |||
} | |||
drmModeFreeEncoder(enc); | |||
} | |||
} | |||
ret = drmModeSetCrtc(dev->drmFD, | |||
scrn->crtcID, | |||
scrn->fbID, | |||
0, 0, | |||
&scrn->connectorID, 1, | |||
scrn->mode); | |||
if (ret) | |||
goto err_crtc; | |||
if (scrn->dpms) | |||
drmModeConnectorSetProperty(dev->drmFD, | |||
scrn->connectorID, | |||
scrn->dpms->prop_id, | |||
DRM_MODE_DPMS_ON); | |||
surf->screen = scrn; | |||
scrn->surf = surf; | |||
scrn->shown = 1; | |||
return EGL_TRUE; | |||
err_crtc: | |||
scrn->crtcID = 0; | |||
err_fb: | |||
drmModeRmFB(dev->drmFD, scrn->fbID); | |||
drmModeFreeFB(scrn->fb); | |||
scrn->fb = NULL; | |||
err_bo: | |||
pipe_surface_reference(&scrn->surface, NULL); | |||
pipe_texture_reference(&scrn->tex, NULL); | |||
err_tex: | |||
return EGL_FALSE; | |||
} | |||
/** | |||
* Called by libEGL's eglDestroySurface(). | |||
*/ | |||
EGLBoolean | |||
drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) | |||
{ | |||
struct drm_surface *surf = lookup_drm_surface(surface); | |||
if (!_eglIsSurfaceBound(&surf->base)) { | |||
if (surf->screen) | |||
drm_takedown_shown_screen(dpy, surf->screen); | |||
st_unreference_framebuffer(surf->stfb); | |||
free(surf); | |||
} | |||
return EGL_TRUE; | |||
} | |||
/** | |||
* Called by libEGL's eglSwapBuffers(). | |||
*/ | |||
EGLBoolean | |||
drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) | |||
{ | |||
struct drm_device *dev = lookup_drm_device(dpy); | |||
struct drm_surface *surf = lookup_drm_surface(draw); | |||
struct pipe_surface *back_surf; | |||
if (!surf) | |||
return EGL_FALSE; | |||
st_get_framebuffer_surface(surf->stfb, ST_SURFACE_BACK_LEFT, &back_surf); | |||
if (back_surf) { | |||
struct drm_context *ctx = lookup_drm_context(draw->Binding); | |||
st_notify_swapbuffers(surf->stfb); | |||
if (ctx && surf->screen) { | |||
if (ctx->pipe->surface_copy) { | |||
ctx->pipe->surface_copy(ctx->pipe, | |||
surf->screen->surface, | |||
0, 0, | |||
back_surf, | |||
0, 0, | |||
surf->w, surf->h); | |||
} else { | |||
util_surface_copy(ctx->pipe, FALSE, | |||
surf->screen->surface, | |||
0, 0, | |||
back_surf, | |||
0, 0, | |||
surf->w, surf->h); | |||
} | |||
ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL); | |||
#ifdef DRM_MODE_FEATURE_DIRTYFB | |||
/* TODO query connector property to see if this is needed */ | |||
drmModeDirtyFB(dev->drmFD, surf->screen->fbID, NULL, 0); | |||
#else | |||
(void)dev; | |||
#endif | |||
/* TODO more stuff here */ | |||
} | |||
} | |||
return EGL_TRUE; | |||
} |
@@ -1,272 +0,0 @@ | |||
#include "utils.h" | |||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include "egl_tracker.h" | |||
#include <fcntl.h> | |||
#include "egllog.h" | |||
#include "state_tracker/drm_api.h" | |||
#include "pipe/p_screen.h" | |||
#include "pipe/internal/p_winsys_screen.h" | |||
/** HACK */ | |||
void* driDriverAPI; | |||
/* | |||
* Exported functions | |||
*/ | |||
/** Called by libEGL just prior to unloading/closing the driver. | |||
*/ | |||
static void | |||
drm_unload(_EGLDriver *drv) | |||
{ | |||
free(drv); | |||
} | |||
/** | |||
* The bootstrap function. Return a new drm_driver object and | |||
* plug in API functions. | |||
* libEGL finds this function with dlopen()/dlsym() and calls it from | |||
* "load driver" function. | |||
*/ | |||
_EGLDriver * | |||
_eglMain(const char *args) | |||
{ | |||
_EGLDriver *drv; | |||
drv = (_EGLDriver *) calloc(1, sizeof(_EGLDriver)); | |||
if (!drv) { | |||
return NULL; | |||
} | |||
/* First fill in the dispatch table with defaults */ | |||
_eglInitDriverFallbacks(drv); | |||
/* then plug in our Drm-specific functions */ | |||
drv->API.Initialize = drm_initialize; | |||
drv->API.Terminate = drm_terminate; | |||
drv->API.CreateContext = drm_create_context; | |||
drv->API.MakeCurrent = drm_make_current; | |||
drv->API.CreateWindowSurface = drm_create_window_surface; | |||
drv->API.CreatePixmapSurface = drm_create_pixmap_surface; | |||
drv->API.CreatePbufferSurface = drm_create_pbuffer_surface; | |||
drv->API.DestroySurface = drm_destroy_surface; | |||
drv->API.DestroyContext = drm_destroy_context; | |||
drv->API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; | |||
drv->API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; | |||
drv->API.SwapBuffers = drm_swap_buffers; | |||
drv->Name = "DRM/Gallium/Win"; | |||
drv->Unload = drm_unload; | |||
return drv; | |||
} | |||
static void | |||
drm_get_device_id(struct drm_device *device) | |||
{ | |||
char path[512]; | |||
FILE *file; | |||
char *ret; | |||
/* TODO get the real minor */ | |||
int minor = 0; | |||
device->deviceID = 0; | |||
snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); | |||
file = fopen(path, "r"); | |||
if (!file) { | |||
_eglLog(_EGL_WARNING, "Could not retrive device ID\n"); | |||
return; | |||
} | |||
ret = fgets(path, sizeof( path ), file); | |||
fclose(file); | |||
if (!ret) | |||
return; | |||
sscanf(path, "%x", &device->deviceID); | |||
} | |||
static void | |||
drm_update_res(struct drm_device *dev) | |||
{ | |||
drmModeFreeResources(dev->res); | |||
dev->res = drmModeGetResources(dev->drmFD); | |||
} | |||
static void | |||
drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) | |||
{ | |||
drmModeModeInfoPtr m = NULL; | |||
int i; | |||
for (i = 0; i < connector->count_modes; i++) { | |||
m = &connector->modes[i]; | |||
_eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); | |||
} | |||
} | |||
static void | |||
drm_find_dpms(struct drm_device *dev, struct drm_screen *screen) | |||
{ | |||
drmModeConnectorPtr c = screen->connector; | |||
drmModePropertyPtr p; | |||
int i; | |||
for (i = 0; i < c->count_props; i++) { | |||
p = drmModeGetProperty(dev->drmFD, c->props[i]); | |||
if (!strcmp(p->name, "DPMS")) | |||
break; | |||
drmModeFreeProperty(p); | |||
p = NULL; | |||
} | |||
screen->dpms = p; | |||
} | |||
static int drm_open_minor(int minor) | |||
{ | |||
char buf[64]; | |||
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); | |||
return open(buf, O_RDWR, 0); | |||
} | |||
EGLBoolean | |||
drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) | |||
{ | |||
struct drm_device *dev; | |||
struct drm_screen *screen = NULL; | |||
drmModeConnectorPtr connector = NULL; | |||
drmModeResPtr res = NULL; | |||
unsigned count_connectors = 0; | |||
int num_screens = 0; | |||
EGLint i; | |||
int fd; | |||
_EGLConfig *config; | |||
dev = (struct drm_device *) calloc(1, sizeof(struct drm_device)); | |||
if (!dev) | |||
return EGL_FALSE; | |||
dev->api = drm_api_create(); | |||
/* try the first node */ | |||
fd = drm_open_minor(0); | |||
if (fd < 0) | |||
goto err_fd; | |||
dev->drmFD = fd; | |||
drm_get_device_id(dev); | |||
dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL); | |||
if (!dev->screen) | |||
goto err_screen; | |||
dev->winsys = dev->screen->winsys; | |||
drm_update_res(dev); | |||
res = dev->res; | |||
if (res) | |||
count_connectors = res->count_connectors; | |||
else | |||
_eglLog(_EGL_WARNING, "Could not retrive kms information\n"); | |||
for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { | |||
connector = drmModeGetConnector(fd, res->connectors[i]); | |||
if (!connector) | |||
continue; | |||
if (connector->connection != DRM_MODE_CONNECTED) { | |||
drmModeFreeConnector(connector); | |||
continue; | |||
} | |||
screen = malloc(sizeof(struct drm_screen)); | |||
memset(screen, 0, sizeof(*screen)); | |||
screen->connector = connector; | |||
screen->connectorID = connector->connector_id; | |||
_eglInitScreen(&screen->base); | |||
_eglAddScreen(disp, &screen->base); | |||
drm_add_modes_from_connector(&screen->base, connector); | |||
drm_find_dpms(dev, screen); | |||
dev->screens[num_screens++] = screen; | |||
} | |||
dev->count_screens = num_screens; | |||
disp->DriverData = dev; | |||
/* for now we only have one config */ | |||
config = calloc(1, sizeof(*config)); | |||
memset(config, 1, sizeof(*config)); | |||
_eglInitConfig(config, 1); | |||
_eglSetConfigAttrib(config, EGL_RED_SIZE, 8); | |||
_eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); | |||
_eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); | |||
_eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); | |||
_eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); | |||
_eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); | |||
_eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); | |||
_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); | |||
_eglAddConfig(disp, config); | |||
disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; | |||
/* enable supported extensions */ | |||
disp->Extensions.MESA_screen_surface = EGL_TRUE; | |||
disp->Extensions.MESA_copy_context = EGL_TRUE; | |||
*major = 1; | |||
*minor = 4; | |||
return EGL_TRUE; | |||
err_screen: | |||
drmClose(fd); | |||
err_fd: | |||
free(dev); | |||
return EGL_FALSE; | |||
} | |||
EGLBoolean | |||
drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy) | |||
{ | |||
struct drm_device *dev = lookup_drm_device(dpy); | |||
struct drm_screen *screen; | |||
int i = 0; | |||
_eglReleaseDisplayResources(drv, dpy); | |||
_eglCleanupDisplay(dpy); | |||
drmFreeVersion(dev->version); | |||
for (i = 0; i < dev->count_screens; i++) { | |||
screen = dev->screens[i]; | |||
if (screen->shown) | |||
drm_takedown_shown_screen(dpy, screen); | |||
drmModeFreeProperty(screen->dpms); | |||
drmModeFreeConnector(screen->connector); | |||
_eglDestroyScreen(&screen->base); | |||
dev->screens[i] = NULL; | |||
} | |||
dev->screen->destroy(dev->screen); | |||
dev->winsys = NULL; | |||
drmClose(dev->drmFD); | |||
dev->api->destroy(dev->api); | |||
free(dev); | |||
dpy->DriverData = NULL; | |||
return EGL_TRUE; | |||
} |
@@ -1,195 +0,0 @@ | |||
#ifndef _EGL_TRACKER_H_ | |||
#define _EGL_TRACKER_H_ | |||
#include <stdint.h> | |||
#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 | |||
{ | |||
/* | |||
* pipe | |||
*/ | |||
struct drm_api *api; | |||
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_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_texture *tex; | |||
struct pipe_surface *surface; | |||
/* | |||
* drm | |||
*/ | |||
struct { | |||
unsigned height; | |||
unsigned width; | |||
unsigned pitch; | |||
unsigned handle; | |||
} front; | |||
/* currently only support one connector */ | |||
drmModeConnectorPtr connector; | |||
uint32_t connectorID; | |||
/* dpms property */ | |||
drmModePropertyPtr dpms; | |||
/* 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; | |||
drmModeModeInfoPtr mode; | |||
}; | |||
static INLINE struct drm_device * | |||
lookup_drm_device(_EGLDisplay *d) | |||
{ | |||
return (struct drm_device *) d->DriverData; | |||
} | |||
static INLINE struct drm_context * | |||
lookup_drm_context(_EGLContext *c) | |||
{ | |||
return (struct drm_context *) c; | |||
} | |||
static INLINE struct drm_surface * | |||
lookup_drm_surface(_EGLSurface *s) | |||
{ | |||
return (struct drm_surface *) s; | |||
} | |||
static INLINE struct drm_screen * | |||
lookup_drm_screen(_EGLScreen *s) | |||
{ | |||
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(_EGLDisplay *dpy, 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 *conf, _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 *conf, NativeWindowType window, const EGLint *attrib_list); | |||
_EGLSurface *drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list); | |||
_EGLSurface *drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); | |||
_EGLSurface *drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); | |||
EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode); | |||
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 |
@@ -1,85 +0,0 @@ | |||
#include "egl_tracker.h" | |||
#include "egllog.h" | |||
void | |||
drm_visual_modes_destroy(__GLcontextModes *modes) | |||
{ | |||
_eglLog(_EGL_DEBUG, "%s", __FUNCTION__); | |||
while (modes) { | |||
__GLcontextModes * const next = modes->next; | |||
free(modes); | |||
modes = next; | |||
} | |||
} | |||
__GLcontextModes * | |||
drm_visual_modes_create(unsigned count, size_t minimum_size) | |||
{ | |||
/* This code copied from libGLX, and modified */ | |||
const size_t size = (minimum_size > sizeof(__GLcontextModes)) | |||
? minimum_size : sizeof(__GLcontextModes); | |||
__GLcontextModes * head = NULL; | |||
__GLcontextModes ** next; | |||
unsigned i; | |||
_eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); | |||
next = & head; | |||
for (i = 0 ; i < count ; i++) { | |||
*next = (__GLcontextModes *) calloc(1, size); | |||
if (*next == NULL) { | |||
drm_visual_modes_destroy(head); | |||
head = NULL; | |||
break; | |||
} | |||
(*next)->doubleBufferMode = 1; | |||
(*next)->visualID = GLX_DONT_CARE; | |||
(*next)->visualType = GLX_DONT_CARE; | |||
(*next)->visualRating = GLX_NONE; | |||
(*next)->transparentPixel = GLX_NONE; | |||
(*next)->transparentRed = GLX_DONT_CARE; | |||
(*next)->transparentGreen = GLX_DONT_CARE; | |||
(*next)->transparentBlue = GLX_DONT_CARE; | |||
(*next)->transparentAlpha = GLX_DONT_CARE; | |||
(*next)->transparentIndex = GLX_DONT_CARE; | |||
(*next)->xRenderable = GLX_DONT_CARE; | |||
(*next)->fbconfigID = GLX_DONT_CARE; | |||
(*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; | |||
(*next)->bindToTextureRgb = GLX_DONT_CARE; | |||
(*next)->bindToTextureRgba = GLX_DONT_CARE; | |||
(*next)->bindToMipmapTexture = GLX_DONT_CARE; | |||
(*next)->bindToTextureTargets = 0; | |||
(*next)->yInverted = GLX_DONT_CARE; | |||
next = & ((*next)->next); | |||
} | |||
return head; | |||
} | |||
__GLcontextModes * | |||
drm_visual_from_config(_EGLConfig *conf) | |||
{ | |||
__GLcontextModes *visual; | |||
(void)conf; | |||
visual = drm_visual_modes_create(1, sizeof(*visual)); | |||
visual->redBits = 8; | |||
visual->greenBits = 8; | |||
visual->blueBits = 8; | |||
visual->alphaBits = 8; | |||
visual->rgbBits = 32; | |||
visual->doubleBufferMode = 1; | |||
visual->depthBits = 24; | |||
visual->haveDepthBuffer = visual->depthBits > 0; | |||
visual->stencilBits = 8; | |||
visual->haveStencilBuffer = visual->stencilBits > 0; | |||
return visual; | |||
} |
@@ -1,29 +0,0 @@ | |||
TOP = ../../../../../.. | |||
GALLIUMDIR = ../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = EGL_i965.so | |||
PIPE_DRIVERS = \ | |||
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ | |||
$(GALLIUMDIR)/winsys/drm/i965/gem/libi965drm.a \ | |||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ | |||
$(TOP)/src/gallium/drivers/trace/libtrace.a \ | |||
$(TOP)/src/gallium/drivers/i965/libi965.a | |||
DRIVER_SOURCES = | |||
C_SOURCES = \ | |||
$(COMMON_GALLIUM_SOURCES) \ | |||
$(DRIVER_SOURCES) | |||
DRIVER_EXTRAS = -ldrm_intel | |||
ASM_SOURCES = | |||
DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \ | |||
&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") | |||
include ../../Makefile.template | |||
symlinks: |
@@ -1,38 +0,0 @@ | |||
TOP = ../../../../../.. | |||
GALLIUMDIR = ../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = egl_i915.so | |||
PIPE_DRIVERS = \ | |||
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ | |||
$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ | |||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ | |||
$(TOP)/src/gallium/drivers/trace/libtrace.a \ | |||
$(TOP)/src/gallium/drivers/i915/libi915.a | |||
DRIVER_EXTRAS = -lm -lpthread -ldrm_intel | |||
OBJECTS = dummy.o | |||
default: $(TOP)/$(LIB_DIR)/$(LIBNAME) | |||
$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) | |||
@mkdir -p $(TOP)/$(LIB_DIR) | |||
$(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) | |||
$(LIBNAME): $(OBJECTS) $(GALLIUM_AUXILIARIES) $(PIPE_DRIVERS) Makefile | |||
$(MKLIB) -noprefix -o $@ $(OBJECTS) \ | |||
-Wl,--whole-archive $(PIPE_DRIVERS) -Wl,--no-whole-archive \ | |||
-Wl,--start-group $(GALLIUM_AUXILIARIES) -Wl,--end-group \ | |||
$(DRI_LIB_DEPS) $(DRIVER_EXTRAS) | |||
clean: | |||
-rm -f *.o *.so *~ | |||
depend: | |||
symlinks: | |||
install: $(LIBNAME) | |||
$(MINSTALL) -m 755 $(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR) |
@@ -1 +0,0 @@ | |||
/* mklib expects at least one .o is given */ |
@@ -1,38 +0,0 @@ | |||
TOP = ../../../../../.. | |||
GALLIUMDIR = ../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = egl_radeon.so | |||
PIPE_DRIVERS = \ | |||
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ | |||
$(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \ | |||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ | |||
$(TOP)/src/gallium/drivers/trace/libtrace.a \ | |||
$(TOP)/src/gallium/drivers/r300/libr300.a | |||
DRIVER_EXTRAS = -lm -lpthread -ldrm_radeon | |||
OBJECTS = dummy.o | |||
default: $(TOP)/$(LIB_DIR)/$(LIBNAME) | |||
$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) | |||
@mkdir -p $(TOP)/$(LIB_DIR) | |||
$(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) | |||
$(LIBNAME): $(OBJECTS) $(GALLIUM_AUXILIARIES) $(PIPE_DRIVERS) Makefile | |||
$(MKLIB) -noprefix -o $@ $(OBJECTS) \ | |||
-Wl,--whole-archive $(PIPE_DRIVERS) -Wl,--no-whole-archive \ | |||
-Wl,--start-group $(GALLIUM_AUXILIARIES) -Wl,--end-group \ | |||
$(DRI_LIB_DEPS) $(DRIVER_EXTRAS) | |||
clean: | |||
-rm -f *.o *.so *~ | |||
depend: | |||
symlinks: | |||
install: $(LIBNAME) | |||
$(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) |
@@ -1 +0,0 @@ | |||
/* mklib expects at least one .o is given */ |
@@ -1,18 +0,0 @@ | |||
TOP = ../../../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = EGL_svga.so | |||
PIPE_DRIVERS = \ | |||
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ | |||
$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \ | |||
$(TOP)/src/gallium/drivers/trace/libtrace.a \ | |||
$(TOP)/src/gallium/drivers/svga/libsvga.a | |||
C_SOURCES = \ | |||
$(COMMON_GALLIUM_SOURCES) | |||
include ../../Makefile.template | |||
symlinks: |