diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2008-07-11 00:05:53 +1000 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2008-07-11 00:05:53 +1000 |
commit | 19171ab1d30f14ac0d39894125a3d53a91ca5b89 (patch) | |
tree | 7adb5b8317f9acfe1f4f0ba2e10dd79b228cd57d /src/gallium | |
parent | 225863aeb5f2dfe4980ae5887f5623ecb05e9ced (diff) | |
parent | 64f92e00c8292113f9a6372959febe903af09db6 (diff) |
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src/gallium')
19 files changed, 319 insertions, 97 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 9140faeea9..85a75525c8 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -37,6 +37,8 @@ static unsigned trim( unsigned count, unsigned first, unsigned incr ) { + if (count < first) + return 0; return count - (count - first) % incr; } diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 6b92811870..8e834501a4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -184,7 +184,6 @@ boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear ) if (!load_input( cp, i, linear )) return FALSE; cp->insn_counter++; - debug_printf("\n"); } return TRUE; @@ -316,7 +315,6 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) aos_release_xmm_reg( cp, data.idx ); cp->insn_counter++; - debug_printf("\n"); } return TRUE; diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 83ea0be74b..8505d333bd 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -221,7 +221,7 @@ pb_check_alignment(size_t requested, size_t provided) static INLINE boolean pb_check_usage(unsigned requested, unsigned provided) { - return (requested & provided) == provided ? TRUE : FALSE; + return (requested & provided) == requested ? TRUE : FALSE; } diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 92aff88925..a395c630cc 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -573,7 +573,8 @@ tgsi_dump_declaration( if (decl->Declaration.Semantic) { TXT( ", " ); ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); - if (decl->Semantic.SemanticIndex != 0) { + if (decl->Semantic.SemanticIndex != 0 || + decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) { CHR( '[' ); UID( decl->Semantic.SemanticIndex ); CHR( ']' ); diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 2815e61345..cf4964b26b 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -581,6 +581,7 @@ i915_texture_create(struct pipe_screen *screen, struct i915_screen *i915screen = i915_screen(screen); struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); + size_t tex_size; if (!tex) return NULL; @@ -600,14 +601,22 @@ i915_texture_create(struct pipe_screen *screen, goto fail; } + tex_size = tex->stride * tex->total_nblocksy; + tex->buffer = ws->buffer_create(ws, 64, PIPE_BUFFER_USAGE_PIXEL, - tex->stride * - tex->total_nblocksy); + tex_size); if (!tex->buffer) goto fail; +#if 0 + void *ptr = ws->buffer_map(ws, tex->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE); + memset(ptr, 0x80, tex_size); + ws->buffer_unmap(ws, tex->buffer); +#endif + return &tex->base; fail: @@ -710,6 +719,8 @@ i915_texture_blanket(struct pipe_screen * screen, return NULL; tex->base = *base; + tex->base.refcount = 1; + tex->base.screen = screen; tex->stride = stride[0]; diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 24b91fbc79..901c8f83e7 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -154,8 +154,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, /* note: reference counting */ pipe_buffer_reference(ws, &softpipe->constants[shader].buffer, - buf->buffer); - softpipe->constants[shader].size = buf->size; + buf ? buf->buffer : NULL); + softpipe->constants[shader].size = buf ? buf->size : 0; softpipe->dirty |= SP_NEW_CONSTANTS; } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 4db045cdc3..f775591352 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -122,8 +122,10 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, /* Now extract the goodies: */ - spt->buffer = surf.buffer; + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); spt->stride[0] = surf.stride; + spt->buffer = surf.buffer; return spt->buffer != NULL; } @@ -162,6 +164,39 @@ softpipe_texture_create(struct pipe_screen *screen, } +static struct pipe_texture * +softpipe_texture_blanket(struct pipe_screen * screen, + const struct pipe_texture *base, + const unsigned *stride, + struct pipe_buffer *buffer) +{ + struct softpipe_texture *spt; + assert(screen); + + /* Only supports one type */ + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth[0] != 1) { + return NULL; + } + + spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *base; + spt->base.refcount = 1; + spt->base.screen = screen; + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); + spt->stride[0] = stride[0]; + + pipe_buffer_reference(screen->winsys, &spt->buffer, buffer); + + return &spt->base; +} + + static void softpipe_texture_release(struct pipe_screen *screen, struct pipe_texture **pt) @@ -309,6 +344,7 @@ void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; + screen->texture_blanket = softpipe_texture_blanket; screen->texture_release = softpipe_texture_release; screen->get_tex_surface = softpipe_get_tex_surface; diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index efb57a394e..8db0329615 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -125,6 +125,37 @@ intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned byte return &buffer->base; } +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_buffer *buffer; + + if (!be_buf) + goto err; + + memset(be_buf, 0, sizeof(*be_buf)); + + driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); + driBOSetReferenced(be_buf->driBO, handle); + + if (0) /** XXX TODO check error */ + goto err_bo; + + buffer = &be_buf->base; + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(be_buf->driBO); + + return buffer; +err_bo: + free(be_buf); +err: + return NULL; +} + /* * Surface functions. @@ -157,6 +188,7 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) assert((size_t)"intel_i915_surface_release is deprecated" & 0); } + /* * Fence functions */ @@ -189,6 +221,7 @@ intel_be_fence_finish( struct pipe_winsys *sws, return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } + /* * Misc functions */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h index abf0253917..3f8b3f585c 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -48,14 +48,23 @@ struct intel_be_buffer { struct _DriBufferObject *driBO; }; +/** + * Create a be buffer from a drm bo handle + * + * Takes a reference + */ +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle); + static INLINE struct intel_be_buffer * -intel_be_buffer( struct pipe_buffer *buf ) +intel_be_buffer(struct pipe_buffer *buf) { return (struct intel_be_buffer *)buf; } static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) +dri_bo(struct pipe_buffer *buf) { return intel_be_buffer(buf)->driBO; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index cfecebdb8c..f2412217f3 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -49,28 +49,22 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, static void intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) { - struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); struct pipe_screen *screen = intelScreen->base.screen; struct pipe_texture *texture; struct pipe_texture templat; struct pipe_surface *surface; - struct pipe_buffer *buffer = &be_buf->base; + struct pipe_buffer *buffer; unsigned pitch; assert(intelScreen->front.cpp == 4); - /* XXX create a intel_be function for this */ - { - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, handle); - - memset(be_buf, 0, sizeof(*be_buf)); - buffer->refcount = 1; - buffer->alignment = 0; - buffer->usage = 0; - buffer->size = driBOSize(intelScreen->front.buffer); - be_buf->driBO = intelScreen->front.buffer; - } + buffer = intel_be_buffer_from_handle(&intelScreen->base, + "front", handle); + + if (!buffer) + return; + + intelScreen->front.buffer = dri_bo(buffer); memset(&templat, 0, sizeof(templat)); templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile index 9c7ff065ff..e67b49f3ad 100644 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -12,7 +12,7 @@ PIPE_DRIVERS = \ DRIVER_SOURCES = \ intel_swapbuffers.c \ intel_context.c \ - intel_screen.c \ + intel_device.c \ intel_egl.c C_SOURCES = \ diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 7205fa4483..927addb834 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -27,7 +27,7 @@ #include "i915simple/i915_screen.h" -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" @@ -147,13 +147,13 @@ int intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv; + struct intel_device *device = (struct intel_device *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; egl_context->priv = intel; - intel->intel_screen = screen; + intel->intel_device = device; intel->egl_context = egl_context; intel->egl_device = egl_context->device; @@ -161,23 +161,37 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes intel->base.hardware_unlock = intel_unlock_hardware; intel->base.hardware_locked = intel_locked_hardware; - intel_be_init_context(&intel->base, &screen->base); + intel_be_init_context(&intel->base, &device->base); #if 0 pipe = intel_create_softpipe(intel, screen->winsys); #else - pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base); + pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); #endif pipe->priv = intel; intel->st = st_create_context(pipe, visual, st_share); - screen->dummy = intel; + device->dummy = intel; return TRUE; } +int +intel_destroy_context(struct egl_drm_context *egl_context) +{ + struct intel_context *intel = egl_context->priv; + + if (intel->intel_device->dummy == intel) + intel->intel_device->dummy = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + return TRUE; +} + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) { @@ -206,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) { - struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; + struct intel_device *device = (struct intel_device *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; if (draw_fb->front_buffer) @@ -221,7 +235,7 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer draw_fb->front = front; - driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); driBOSetReferenced(draw_fb->front_buffer, front->handle); st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index f05a213ff0..dfa4720b08 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -47,7 +47,7 @@ struct intel_context struct st_context *st; - struct intel_screen *intel_screen; + struct intel_device *intel_device; /* new egl stuff */ struct egl_drm_device *egl_device; @@ -64,7 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - struct intel_screen *screen; + struct intel_device *device; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_device.c index 2818b9676c..b9649cbec7 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -32,7 +32,7 @@ #include "i915simple/i915_screen.h" #include "intel_context.h" -#include "intel_screen.h" +#include "intel_device.h" #include "intel_batchbuffer.h" #include "intel_egl.h" @@ -41,24 +41,23 @@ extern const struct dri_extension card_extensions[]; int -intel_init_driver(struct egl_drm_device *device) +intel_create_device(struct egl_drm_device *device) { - struct intel_screen *intel_screen; + struct intel_device *intel_device; /* Allocate the private area */ - intel_screen = CALLOC_STRUCT(intel_screen); - if (!intel_screen) + intel_device = CALLOC_STRUCT(intel_device); + if (!intel_device) return FALSE; - device->priv = (void *)intel_screen; - intel_screen->device = device; + device->priv = (void *)intel_device; + intel_device->device = device; - /** TODO JB: ugly hack */ - intel_screen->deviceID = PCI_CHIP_I945_GM; + intel_device->deviceID = device->deviceID; - intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); + intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); - intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); + intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); /* hack */ driInitExtensions(NULL, card_extensions, GL_FALSE); @@ -67,6 +66,19 @@ intel_init_driver(struct egl_drm_device *device) } int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device = (struct intel_device *)device->priv; + + intel_be_destroy_device(&intel_device->base); + + free(intel_device); + device->priv = NULL; + + return TRUE; +} + +int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual) { @@ -76,7 +88,7 @@ intel_create_drawable(struct egl_drm_drawable *drawable, if (!intelfb) return GL_FALSE; - intelfb->screen = drawable->device->priv; + intelfb->device = drawable->device->priv; if (visual->redBits == 5) colorFormat = PIPE_FORMAT_R5G6B5_UNORM; @@ -108,6 +120,18 @@ intel_create_drawable(struct egl_drm_drawable *drawable, return GL_FALSE; } - drawable->priv = (void *) intelfb; - return GL_TRUE; + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; } diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_device.h index 9b990b48e7..2f9d4f887e 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ b/src/gallium/winsys/egl_drm/intel/intel_device.h @@ -36,7 +36,7 @@ struct pipe_screen; struct egl_drm_device; struct intel_context; -struct intel_screen +struct intel_device { struct intel_be_device base; struct pipe_screen *pipe; diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 6865bfa3d4..55f4d92afb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -13,6 +13,7 @@ #include "eglmode.h" #include "eglscreen.h" #include "eglsurface.h" +#include "egllog.h" #include "intel_egl.h" @@ -23,18 +24,43 @@ #include "state_tracker/st_public.h" -struct egl_drm_device* egl_drm_create_device(int drmFD); +#define MAX_SCREENS 16 -struct egl_drm_device* +static void +drm_get_device_id(struct egl_drm_device *device) +{ + char path[512]; + FILE *file; + + /* TODO get the real minor */ + int minor = 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; + } + + fgets(path, sizeof( path ), file); + sscanf(path, "%x", &device->deviceID); + fclose(file); +} + +static struct egl_drm_device* egl_drm_create_device(int drmFD) { struct egl_drm_device *device = malloc(sizeof(*device)); memset(device, 0, sizeof(*device)); device->drmFD = drmFD; - if (!intel_init_driver(device)) { - printf("EGL: failed to initalize device\n"); + device->version = drmGetVersion(device->drmFD); + + drm_get_device_id(device); + + if (!intel_create_device(device)) { free(device); + return NULL; } return device; @@ -42,11 +68,17 @@ egl_drm_create_device(int drmFD) __GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); +struct drm_screen; + struct drm_driver { _EGLDriver base; /* base class/object */ drmModeResPtr res; + + struct drm_screen *screens[MAX_SCREENS]; + size_t count_screens; + struct egl_drm_device *device; }; @@ -68,17 +100,26 @@ struct drm_screen { _EGLScreen base; - /* backing buffer and crtc */ + /* 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; + + /* backing buffer */ drmBO buffer; + + /* framebuffer */ drmModeFBPtr fb; uint32_t fbID; - drmModeCrtcPtr crtc; - /* currently only support one connector */ - drmModeConnectorPtr connector; - drmModeEncoderPtr encoder; - uint32_t connectorID; - uint32_t encoderID; + /* crtc and mode used */ + drmModeCrtcPtr crtc; + uint32_t crtcID; struct drm_mode_modeinfo *mode; @@ -105,28 +146,17 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) } } -static void -print_modes(drmModeConnectorPtr connector) -{ - struct drm_mode_modeinfo *m; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh); - } -} static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { - printf("%s enter\n", __FUNCTION__); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_screen *screen = NULL; drmModeConnectorPtr connector = NULL; drmModeResPtr res = NULL; unsigned count_connectors = 0; + int num_screens = 0; EGLint i; int fd; @@ -147,13 +177,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) if (res) count_connectors = res->count_connectors; - for(i = 0; i < count_connectors; i++) { + for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { connector = drmModeGetConnector(fd, res->connectors[i]); if (!connector) continue; - if (connector->connection == DRM_MODE_DISCONNECTED) { + if (connector->connection != DRM_MODE_CONNECTED) { drmModeFreeConnector(connector); continue; } @@ -165,7 +195,9 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); drm_add_modes_from_connector(&screen->base, connector); + drm_drv->screens[num_screens++] = screen; } + drm_drv->count_screens = num_screens; /* for now we only have one config */ _EGLConfig *config = calloc(1, sizeof(*config)); @@ -184,17 +216,64 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drv->Initialized = EGL_TRUE; *major = 1; - *minor = 0; + *minor = 4; return EGL_TRUE; } +static void +drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + + intel_bind_frontbuffer(screen->surf->drawable, NULL); + screen->surf = NULL; + + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[1], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + + drmModeRmFB(drm_drv->device->drmFD, screen->fbID); + drmModeFreeFB(screen->fb); + screen->fb = NULL; + + drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); + + screen->shown = 0; +} static EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy) { - /* TODO: clean up */ - free(drv); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen; + int i = 0; + + intel_destroy_device(drm_drv->device); + drmFreeVersion(drm_drv->device->version); + + for (i = 0; i < drm_drv->count_screens; i++) { + screen = drm_drv->screens[i]; + + if (screen->shown) + drm_takedown_shown_screen(drv, screen); + + drmModeFreeConnector(screen->connector); + _eglDestroyScreen(&screen->base); + drm_drv->screens[i] = NULL; + } + + drmClose(drm_drv->device->drmFD); + + free(drm_drv->device); + + _eglCleanupDisplay(_eglLookupDisplay(dpy)); + free(drm_drv); + return EGL_TRUE; } @@ -237,7 +316,9 @@ visual_from_config(_EGLConfig *conf) visual->doubleBufferMode = 1; visual->depthBits = 24; + visual->haveDepthBuffer = visual->depthBits > 0; visual->stencilBits = 8; + visual->haveStencilBuffer = visual->stencilBits > 0; return visual; } @@ -314,6 +395,8 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) if (fc->base.IsBound) { fc->base.DeletePending = EGL_TRUE; } else { + intel_destroy_context(fc->context); + free(fc->context); free(fc); } return EGL_TRUE; @@ -333,6 +416,7 @@ drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nat return EGL_NO_SURFACE; } + static EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) @@ -480,7 +564,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, size_t size = mode->Height * pitch; int ret; - /* TODO if allready shown take down */ + if (scrn->shown) + drm_takedown_shown_screen(drv, scrn); ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, DRM_BO_FLAG_READ | @@ -490,10 +575,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - if (ret) { - printf("failed to create framebuffer (ret %d)\n", ret); + if (ret) return EGL_FALSE; - } prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); @@ -510,10 +593,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, goto err_bo; scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) { - printf("oh noes, no matching mode found\n"); + if (!scrn->mode) goto err_fb; - } ret = drmModeSetCrtc( drm_drv->device->drmFD, @@ -529,8 +610,11 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, scrn->front.width = mode->Width; scrn->front.height = mode->Height; + scrn->surf = surf; intel_bind_frontbuffer(surf->drawable, &scrn->front); + scrn->shown = 1; + return EGL_TRUE; err_fb: @@ -549,14 +633,15 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) if (fs->base.IsBound) { fs->base.DeletePending = EGL_TRUE; } else { + intel_bind_frontbuffer(fs->drawable, NULL); + intel_destroy_drawable(fs->drawable); + free(fs->drawable); free(fs); } return EGL_TRUE; } - - static EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) { @@ -569,12 +654,15 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re if (!b) return EGL_FALSE; - /* XXX this is where we'd do the hardware context switch */ - (void) drawSurf; - (void) readSurf; - (void) ctx; + if (ctx) { + if (!drawSurf || !readSurf) + return EGL_FALSE; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + } else { + intel_make_current(NULL, NULL, NULL); + } - intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } @@ -602,7 +690,6 @@ _EGLDriver * _eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; - printf("%s enter\n", __FUNCTION__); drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); if (!drm) { @@ -626,6 +713,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) drm->base.API.SwapBuffers = drm_swap_buffers; drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + drm->base.Name = "DRM/Gallium"; /* enable supported extensions */ drm->base.Extensions.MESA_screen_surface = EGL_TRUE; diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h index 18e84e8eea..1ee27e0847 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -2,10 +2,15 @@ #ifndef _INTEL_EGL_H_ #define _INTEL_EGL_H_ +#include <xf86drm.h> + struct egl_drm_device { void *priv; int drmFD; + + drmVersionPtr version; + int deviceID; }; struct egl_drm_context @@ -32,9 +37,15 @@ struct egl_drm_frontbuffer #include "GL/internal/glcore.h" -int intel_init_driver(struct egl_drm_device *device); +int intel_create_device(struct egl_drm_device *device); +int intel_destroy_device(struct egl_drm_device *device); + int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_destroy_context(struct egl_drm_context *context); + int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +int intel_destroy_drawable(struct egl_drm_drawable *drawable); + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); void intel_swap_buffers(struct egl_drm_drawable *draw); void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index bfff6f935f..2edcbc79ff 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" #include "intel_reg.h" @@ -69,7 +69,7 @@ intel_display_surface(struct egl_drm_drawable *draw, //const int srcWidth = surf->width; //const int srcHeight = surf->height; - intel = intel_fb->screen->dummy; + intel = intel_fb->device->dummy; if (!intel) { printf("No dummy context\n"); return; diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 83b8bb95b1..708a58b781 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -535,6 +535,7 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) surf->Base.DeletePending = EGL_TRUE; } else { + XFreeGC(surf->Dpy, surf->Gc); st_unreference_framebuffer(&surf->Framebuffer); free(surf); } |