diff options
author | Michal Krol <[email protected]> | 2010-03-10 15:49:30 +0100 |
---|---|---|
committer | Michal Krol <[email protected]> | 2010-03-10 15:49:30 +0100 |
commit | 3ce4375912c8ea488460e593e07c5bb15b92dca9 (patch) | |
tree | 1011fa439bd829fd46a44fd99478135848800e73 /src/gallium/state_trackers | |
parent | f59f28093ea827bd234d8e1a36bdd56a9fce5f09 (diff) | |
parent | 9b348d0ed125a22be3f318ac60cef6f201edfdab (diff) |
Merge branch 'master' into gallium-sampler-view
Conflicts:
src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/util/u_blitter.c
src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i965/brw_context.h
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_pipe_sampler.c
Diffstat (limited to 'src/gallium/state_trackers')
62 files changed, 1706 insertions, 1511 deletions
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 908cef454e9..2f991c39e33 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -128,7 +128,7 @@ dri_unbind_context(__DRIcontext * cPriv) if (--ctx->bind_count == 0) { if (ctx->st && ctx->st == st_get_current()) { st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); - st_make_current(NULL, NULL, NULL); + st_make_current(NULL, NULL, NULL, NULL); } } } @@ -161,7 +161,13 @@ dri_make_current(__DRIcontext * cPriv, ctx->r_stamp = driReadPriv->lastStamp - 1; } - st_make_current(ctx->st, draw->stfb, read->stfb); + /* DRI co-state tracker currently overrides flush_frontbuffer. + * When this is fixed, will need to pass the drawable in the + * fourth parameter here so that when Mesa calls + * flush_frontbuffer directly (in front-buffer rendering), it + * will have access to the drawable argument: + */ + st_make_current(ctx->st, draw->stfb, read->stfb, NULL); if (__dri1_api_hooks) { dri1_update_drawables(ctx, draw, read); @@ -170,7 +176,7 @@ dri_make_current(__DRIcontext * cPriv, ctx->pipe->priv); } } else { - st_make_current(NULL, NULL, NULL); + st_make_current(NULL, NULL, NULL, NULL); } return GL_TRUE; diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 195ae7b8bc2..458473853cf 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -58,6 +58,7 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_surface *surface = NULL; struct pipe_texture *texture = NULL; struct pipe_texture templat; + struct winsys_handle whandle; memset(&templat, 0, sizeof(templat)); templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; @@ -68,8 +69,11 @@ dri_surface_from_handle(struct drm_api *api, templat.width0 = width; templat.height0 = height; - texture = api->texture_from_shared_handle(api, screen, &templat, - "dri2 buffer", pitch, handle); + memset(&whandle, 0, sizeof(whandle)); + whandle.handle = handle; + whandle.stride = pitch; + + texture = screen->texture_from_handle(screen, &templat, &whandle); if (!texture) { debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__); @@ -134,12 +138,13 @@ dri_get_buffers(__DRIdrawable * dPriv) if ((dri_screen->dri2.loader && (dri_screen->dri2.loader->base.version > 2) - && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) + && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) { buffers = (*dri_screen->dri2.loader->getBuffersWithFormat) (dri_drawable, &dri_drawable->w, &dri_drawable->h, drawable->attachments, drawable->num_attachments, &count, dri_drawable->loaderPrivate); - else + } else { + assert(dri_screen->dri2.loader); buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable, &dri_drawable->w, &dri_drawable->h, @@ -148,6 +153,7 @@ dri_get_buffers(__DRIdrawable * dPriv) num_attachments, &count, dri_drawable-> loaderPrivate); + } if (buffers == NULL) { return; @@ -288,8 +294,6 @@ dri_update_buffer(struct pipe_screen *screen, void *context_private) ctx->r_stamp == *ctx->rPriv->pStamp) return; - st_flush(ctx->st, PIPE_FLUSH_FRAME, NULL); - ctx->d_stamp = *ctx->dPriv->pStamp; ctx->r_stamp = *ctx->rPriv->pStamp; @@ -349,11 +353,11 @@ dri_create_buffer(__DRIscreen * sPriv, if (visual->redBits == 8) { if (visual->alphaBits == 8) - drawable->color_format = PIPE_FORMAT_A8R8G8B8_UNORM; + drawable->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; else - drawable->color_format = PIPE_FORMAT_X8R8G8B8_UNORM; + drawable->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; } else { - drawable->color_format = PIPE_FORMAT_R5G6B5_UNORM; + drawable->color_format = PIPE_FORMAT_B5G6R5_UNORM; } switch(visual->depthBits) { @@ -367,12 +371,12 @@ dri_create_buffer(__DRIscreen * sPriv, case 24: if (visual->stencilBits == 0) { drawable->depth_stencil_format = (screen->d_depth_bits_last) ? - PIPE_FORMAT_X8Z24_UNORM: - PIPE_FORMAT_Z24X8_UNORM; + PIPE_FORMAT_Z24X8_UNORM: + PIPE_FORMAT_X8Z24_UNORM; } else { drawable->depth_stencil_format = (screen->sd_depth_bits_last) ? - PIPE_FORMAT_S8Z24_UNORM: - PIPE_FORMAT_Z24S8_UNORM; + PIPE_FORMAT_Z24S8_UNORM: + PIPE_FORMAT_S8Z24_UNORM; } break; case 32: diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 77d640227fb..60bc560049c 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -109,22 +109,22 @@ dri_fill_in_modes(struct dri_screen *screen, stencil_bits_array[0] = 0; depth_buffer_factor = 1; - pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, + pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, + pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM, + pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM, + pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM, + pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); - pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM, + pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); @@ -139,7 +139,7 @@ dri_fill_in_modes(struct dri_screen *screen, pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM, + pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); } else { diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 80dd1269955..e4972d493d6 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -36,6 +36,7 @@ #include "native.h" #include "egl_g3d.h" +#include "egl_g3d_image.h" #include "egl_st.h" /** @@ -508,35 +509,33 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) } /** - * Flush the front buffer of the context's draw surface. + * Re-validate the context. */ static void -egl_g3d_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, void *context_private) +egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private) { struct egl_g3d_context *gctx = egl_g3d_context(context_private); - struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface); - - if (gsurf) - gsurf->native->flush_frontbuffer(gsurf->native); + egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base); } -/** - * Re-validate the context. - */ static void -egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private) +egl_g3d_invalid_surface(struct native_display *ndpy, + struct native_surface *nsurf, + unsigned int seq_num) { - struct egl_g3d_context *gctx = egl_g3d_context(context_private); + /* XXX not thread safe? */ + struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data); + struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext); - /** - * It is likely that the surface has changed when this function is called. - * Set force_validate to skip an unnecessary check. - */ - gctx->force_validate = EGL_TRUE; - egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base); + /* set force_validate to skip an unnecessary check */ + if (gctx) + gctx->force_validate = TRUE; } +static struct native_event_handler egl_g3d_native_event_handler = { + .invalid_surface = egl_g3d_invalid_surface +}; + static EGLBoolean egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) { @@ -581,31 +580,36 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, } dpy->DriverData = gdpy; - gdpy->native = native_create_display(dpy->NativeDisplay); + gdpy->native = native_create_display(dpy->NativeDisplay, + &egl_g3d_native_event_handler); if (!gdpy->native) { _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); goto fail; } - gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer; + gdpy->native->user_data = (void *) dpy; gdpy->native->screen->update_buffer = egl_g3d_update_buffer; egl_g3d_init_st(&gdrv->base); dpy->ClientAPIsMask = gdrv->api_mask; - if (egl_g3d_add_configs(drv, dpy, 1) == 1) { - _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)"); - goto fail; - } - #ifdef EGL_MESA_screen_surface - /* enable MESA_screen_surface */ + /* enable MESA_screen_surface before adding (and validating) configs */ if (gdpy->native->modeset) { dpy->Extensions.MESA_screen_surface = EGL_TRUE; egl_g3d_add_screens(drv, dpy); } #endif + dpy->Extensions.KHR_image_base = EGL_TRUE; + if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER)) + dpy->Extensions.KHR_image_pixmap = EGL_TRUE; + + if (egl_g3d_add_configs(drv, dpy, 1) == 1) { + _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)"); + goto fail; + } + *major = 1; *minor = 4; @@ -693,131 +697,144 @@ egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) return EGL_TRUE; } -static EGLBoolean -init_surface_geometry(_EGLSurface *surf) -{ - struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - - return gsurf->native->validate(gsurf->native, 0x0, - &gsurf->sequence_number, NULL, - &gsurf->base.Width, &gsurf->base.Height); -} +struct egl_g3d_create_surface_arg { + EGLint type; + union { + EGLNativeWindowType win; + EGLNativePixmapType pix; + } u; +}; static _EGLSurface * -egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLConfig *conf, EGLNativeWindowType win, - const EGLint *attribs) +egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + struct egl_g3d_create_surface_arg *arg, + const EGLint *attribs) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_config *gconf = egl_g3d_config(conf); struct egl_g3d_surface *gsurf; + struct native_surface *nsurf; + const char *err; + + switch (arg->type) { + case EGL_WINDOW_BIT: + err = "eglCreateWindowSurface"; + break; + case EGL_PIXMAP_BIT: + err = "eglCreatePixmapSurface"; + break; + case EGL_PBUFFER_BIT: + err = "eglCreatePBufferSurface"; + break; +#ifdef EGL_MESA_screen_surface + case EGL_SCREEN_BIT_MESA: + err = "eglCreateScreenSurface"; + break; +#endif + default: + err = "eglCreateUnknownSurface"; + break; + } gsurf = CALLOC_STRUCT(egl_g3d_surface); if (!gsurf) { - _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); + _eglError(EGL_BAD_ALLOC, err); return NULL; } - if (!_eglInitSurface(&gsurf->base, dpy, EGL_WINDOW_BIT, conf, attribs)) { + if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) { free(gsurf); return NULL; } - gsurf->native = - gdpy->native->create_window_surface(gdpy->native, win, gconf->native); - if (!gsurf->native) { + /* create the native surface */ + switch (arg->type) { + case EGL_WINDOW_BIT: + nsurf = gdpy->native->create_window_surface(gdpy->native, + arg->u.win, gconf->native); + break; + case EGL_PIXMAP_BIT: + nsurf = gdpy->native->create_pixmap_surface(gdpy->native, + arg->u.pix, gconf->native); + break; + case EGL_PBUFFER_BIT: + nsurf = gdpy->native->create_pbuffer_surface(gdpy->native, + gconf->native, gsurf->base.Width, gsurf->base.Height); + break; +#ifdef EGL_MESA_screen_surface + case EGL_SCREEN_BIT_MESA: + /* prefer back buffer (move to _eglInitSurface?) */ + gsurf->base.RenderBuffer = EGL_BACK_BUFFER; + nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native, + gconf->native, gsurf->base.Width, gsurf->base.Height); + break; +#endif + default: + nsurf = NULL; + break; + } + + if (!nsurf) { free(gsurf); return NULL; } - - if (!init_surface_geometry(&gsurf->base)) { - gsurf->native->destroy(gsurf->native); + /* initialize the geometry */ + if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL, + &gsurf->base.Width, &gsurf->base.Height)) { + nsurf->destroy(nsurf); free(gsurf); return NULL; } - gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER || - !gconf->native->mode.doubleBufferMode) ? + nsurf->user_data = &gsurf->base; + gsurf->native = nsurf; + + gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ? NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; + if (!gconf->native->mode.doubleBufferMode) + gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT; return &gsurf->base; } static _EGLSurface * -egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLConfig *conf, EGLNativePixmapType pix, +egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, EGLNativeWindowType win, const EGLint *attribs) { - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct egl_g3d_config *gconf = egl_g3d_config(conf); - struct egl_g3d_surface *gsurf; + struct egl_g3d_create_surface_arg arg; - gsurf = CALLOC_STRUCT(egl_g3d_surface); - if (!gsurf) { - _eglError(EGL_BAD_ALLOC, "eglCreatePixmapSurface"); - return NULL; - } + memset(&arg, 0, sizeof(arg)); + arg.type = EGL_WINDOW_BIT; + arg.u.win = win; - if (!_eglInitSurface(&gsurf->base, dpy, EGL_PIXMAP_BIT, conf, attribs)) { - free(gsurf); - return NULL; - } - - gsurf->native = - gdpy->native->create_pixmap_surface(gdpy->native, pix, gconf->native); - if (!gsurf->native) { - free(gsurf); - return NULL; - } + return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs); +} - if (!init_surface_geometry(&gsurf->base)) { - gsurf->native->destroy(gsurf->native); - free(gsurf); - return NULL; - } +static _EGLSurface * +egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, EGLNativePixmapType pix, + const EGLint *attribs) +{ + struct egl_g3d_create_surface_arg arg; - gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT; + memset(&arg, 0, sizeof(arg)); + arg.type = EGL_PIXMAP_BIT; + arg.u.pix = pix; - return &gsurf->base; + return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs); } static _EGLSurface * egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attribs) { - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct egl_g3d_config *gconf = egl_g3d_config(conf); - struct egl_g3d_surface *gsurf; - - gsurf = CALLOC_STRUCT(egl_g3d_surface); - if (!gsurf) { - _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); - return NULL; - } - - if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) { - free(gsurf); - return NULL; - } - - gsurf->native = - gdpy->native->create_pbuffer_surface(gdpy->native, gconf->native, - gsurf->base.Width, gsurf->base.Height); - if (!gsurf->native) { - free(gsurf); - return NULL; - } + struct egl_g3d_create_surface_arg arg; - if (!init_surface_geometry(&gsurf->base)) { - gsurf->native->destroy(gsurf->native); - free(gsurf); - return NULL; - } - - gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ? - NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; + memset(&arg, 0, sizeof(arg)); + arg.type = EGL_PBUFFER_BIT; - return &gsurf->base; + return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs); } /** @@ -875,8 +892,13 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, if (gctx) { ok = egl_g3d_realloc_context(dpy, &gctx->base); if (ok) { + /* XXX: need to pass the winsys argument for + * flush_frontbuffer in the fourth parameter here: + */ ok = gctx->stapi->st_make_current(gctx->st_ctx, - gctx->draw.st_fb, gctx->read.st_fb); + gctx->draw.st_fb, + gctx->read.st_fb, + NULL); if (ok) { egl_g3d_validate_context(dpy, &gctx->base); if (gdraw->base.Type == EGL_WINDOW_BIT) { @@ -888,7 +910,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, } } else if (old_gctx) { - ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL); + ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL, NULL); old_gctx->base.WindowRenderBuffer = EGL_NONE; } @@ -925,32 +947,14 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) if (gctx) gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb); - /* - * We drew on the back buffer, unless there was no back buffer. - * In that case, we drew on the front buffer. Either case, we call - * swap_buffers. - */ - if (!gsurf->native->swap_buffers(gsurf->native)) - return EGL_FALSE; - - if (gctx) { - struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); - - /* force validation if the swap method is not copy */ - if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML) { - gctx->force_validate = EGL_TRUE; - egl_g3d_validate_context(dpy, &gctx->base); - } - } - - return EGL_TRUE; + return gsurf->native->swap_buffers(gsurf->native); } /** * Find a config that supports the pixmap. */ -static _EGLConfig * -find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix) +_EGLConfig * +egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_config *gconf; @@ -1002,7 +1006,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, if (!gsurf->render_surface) return EGL_TRUE; - gconf = egl_g3d_config(find_pixmap_config(dpy, target)); + gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target)); if (!gconf) return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); @@ -1109,7 +1113,7 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, target_format = PIPE_FORMAT_R8G8B8_UNORM; break; case EGL_TEXTURE_RGBA: - target_format = PIPE_FORMAT_A8R8G8B8_UNORM; + target_format = PIPE_FORMAT_B8G8R8A8_UNORM; break; default: return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); @@ -1177,34 +1181,12 @@ static _EGLSurface * egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attribs) { - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct egl_g3d_config *gconf = egl_g3d_config(conf); - struct egl_g3d_surface *gsurf; + struct egl_g3d_create_surface_arg arg; - gsurf = CALLOC_STRUCT(egl_g3d_surface); - if (!gsurf) { - _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); - return NULL; - } + memset(&arg, 0, sizeof(arg)); + arg.type = EGL_SCREEN_BIT_MESA; - if (!_eglInitSurface(&gsurf->base, dpy, - EGL_SCREEN_BIT_MESA, conf, attribs)) { - free(gsurf); - return NULL; - } - - gsurf->native = - gdpy->native->modeset->create_scanout_surface(gdpy->native, - gconf->native, gsurf->base.Width, gsurf->base.Height); - if (!gsurf->native) { - free(gsurf); - return NULL; - } - - gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ? - NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; - - return &gsurf->base; + return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs); } static EGLBoolean @@ -1335,6 +1317,9 @@ _eglMain(const char *args) gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image; gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image; + gdrv->base.API.CreateImageKHR = egl_g3d_create_image; + gdrv->base.API.DestroyImageKHR = egl_g3d_destroy_image; + #ifdef EGL_MESA_screen_surface gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface; gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h index 5d2d9c481ab..e3e55e46d3b 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -34,6 +34,7 @@ #include "eglcontext.h" #include "eglsurface.h" #include "eglconfig.h" +#include "eglimage.h" #include "eglscreen.h" #include "eglmode.h" @@ -81,6 +82,14 @@ struct egl_g3d_config { const struct native_config *native; }; +struct egl_g3d_image { + _EGLImage base; + struct pipe_texture *texture; + unsigned face; + unsigned level; + unsigned zslice; +}; + struct egl_g3d_screen { _EGLScreen base; const struct native_connector *native; @@ -90,5 +99,10 @@ struct egl_g3d_screen { /* standard typecasts */ _EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d) _EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj) +_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj) + + +_EGLConfig * +egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix); #endif /* _EGL_G3D_H_ */ diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c new file mode 100644 index 00000000000..d701f9c9a88 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c @@ -0,0 +1,136 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <[email protected]> + */ + +#include <assert.h> +#include "pipe/p_screen.h" +#include "util/u_memory.h" +#include "util/u_rect.h" +#include "util/u_inlines.h" +#include "eglcurrent.h" +#include "egllog.h" + +#include "native.h" +#include "egl_g3d.h" +#include "egl_g3d_image.h" + +/** + * Reference and return the front left buffer of the native pixmap. + */ +static struct pipe_texture * +egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf; + struct native_surface *nsurf; + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + enum native_attachment natt; + + gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, pix)); + if (!gconf) + return NULL; + + nsurf = gdpy->native->create_pixmap_surface(gdpy->native, + pix, gconf->native); + if (!nsurf) + return NULL; + + natt = NATIVE_ATTACHMENT_FRONT_LEFT; + if (!nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL)) + textures[natt] = NULL; + + nsurf->destroy(nsurf); + + return textures[natt]; +} + +_EGLImage * +egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, + EGLenum target, EGLClientBuffer buffer, + const EGLint *attribs) +{ + struct pipe_texture *ptex; + struct egl_g3d_image *gimg; + unsigned face = 0, level = 0, zslice = 0; + + gimg = CALLOC_STRUCT(egl_g3d_image); + if (!gimg) { + _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); + return NULL; + } + + if (!_eglInitImage(&gimg->base, dpy, attribs)) { + free(gimg); + return NULL; + } + + switch (target) { + case EGL_NATIVE_PIXMAP_KHR: + ptex = egl_g3d_reference_native_pixmap(dpy, + (EGLNativePixmapType) buffer); + break; + default: + ptex = NULL; + break; + } + + if (!ptex) { + free(gimg); + return NULL; + } + + if (level > ptex->last_level) { + _eglError(EGL_BAD_MATCH, "eglCreateEGLImageKHR"); + pipe_texture_reference(&gimg->texture, NULL); + free(gimg); + return NULL; + } + if (zslice > ptex->depth0) { + _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); + pipe_texture_reference(&gimg->texture, NULL); + free(gimg); + return NULL; + } + + /* transfer the ownership to the image */ + gimg->texture = ptex; + gimg->face = face; + gimg->level = level; + gimg->zslice = zslice; + + return &gimg->base; +} + +EGLBoolean +egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img) +{ + struct egl_g3d_image *gimg = egl_g3d_image(img); + + pipe_texture_reference(&gimg->texture, NULL); + free(gimg); + + return EGL_TRUE; +} diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.h b/src/gallium/state_trackers/egl/common/egl_g3d_image.h new file mode 100644 index 00000000000..c199c466456 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.h @@ -0,0 +1,41 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <[email protected]> + */ + +#ifndef _EGL_G3D_IMAGE_H_ +#define _EGL_G3D_IMAGE_H_ + +#include "egl_g3d.h" + +_EGLImage * +egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, + EGLenum target, EGLClientBuffer buffer, + const EGLint *attribs); + +EGLBoolean +egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image); + +#endif /* _EGL_G3D_IMAGE_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h index 4f9758545ab..93c81b26e10 100644 --- a/src/gallium/state_trackers/egl/common/native.h +++ b/src/gallium/state_trackers/egl/common/native.h @@ -34,6 +34,8 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "native_modeset.h" + /** * Only color buffers are listed. The others are allocated privately through, * for example, st_renderbuffer_alloc_storage(). @@ -47,6 +49,14 @@ enum native_attachment { NUM_NATIVE_ATTACHMENTS }; +enum native_param_type { + /* + * Return TRUE if window/pixmap surfaces use the buffers of the native + * types. + */ + NATIVE_PARAM_USE_NATIVE_BUFFER +}; + /** * Enumerations for probe results. */ @@ -69,6 +79,11 @@ struct native_probe { }; struct native_surface { + /** + * Available for caller's use. + */ + void *user_data; + void (*destroy)(struct native_surface *nsurf); /** @@ -117,18 +132,6 @@ struct native_config { boolean scanout_bit; }; -struct native_connector { - int dummy; -}; - -struct native_mode { - const char *desc; - int width, height; - int refresh_rate; -}; - -struct native_display_modeset; - /** * A pipe winsys abstracts the OS. A pipe screen abstracts the graphcis * hardware. A native display consists of a pipe winsys, a pipe screen, and @@ -137,15 +140,25 @@ struct native_display_modeset; struct native_display { /** * The pipe screen of the native display. - * - * Note that the "flush_frontbuffer" and "update_buffer" callbacks will be - * overridden. */ struct pipe_screen *screen; + /** + * Available for caller's use. + */ + void *user_data; + void (*destroy)(struct native_display *ndpy); /** + * Query the parameters of the native display. + * + * The return value is defined by the parameter. + */ + int (*get_param)(struct native_display *ndpy, + enum native_param_type param); + + /** * Get the supported configs. The configs are owned by the display, but * the returned array should be free()ed. * @@ -196,46 +209,17 @@ struct native_display { }; /** - * Mode setting interface of the native display. It exposes the mode setting - * capabilities of the underlying graphics hardware. + * The handler for events that a native display may generate. The events are + * generated asynchronously and the handler may be called by any thread at any + * time. */ -struct native_display_modeset { - /** - * Get the available physical connectors and the number of CRTCs. - */ - const struct native_connector **(*get_connectors)(struct native_display *ndpy, - int *num_connectors, - int *num_crtcs); - - /** - * Get the current supported modes of a connector. The returned modes may - * change every time this function is called and those from previous calls - * might become invalid. - */ - const struct native_mode **(*get_modes)(struct native_display *ndpy, - const struct native_connector *nconn, - int *num_modes); - - /** - * Create a scan-out surface. Required unless no config has - * GLX_SCREEN_BIT_MESA set. - */ - struct native_surface *(*create_scanout_surface)(struct native_display *ndpy, - const struct native_config *nconf, - uint width, uint height); - +struct native_event_handler { /** - * Program the CRTC to output the surface to the given connectors with the - * given mode. When surface is not given, the CRTC is disabled. - * - * This interface does not export a way to query capabilities of the CRTCs. - * The native display usually needs to dynamically map the index to a CRTC - * that supports the given connectors. + * This function is called when a surface needs to be validated. */ - boolean (*program)(struct native_display *ndpy, int crtc_idx, - struct native_surface *nsurf, uint x, uint y, - const struct native_connector **nconns, int num_nconns, - const struct native_mode *nmode); + void (*invalid_surface)(struct native_display *ndpy, + struct native_surface *nsurf, + unsigned int seq_num); }; /** @@ -267,6 +251,7 @@ const char * native_get_name(void); struct native_display * -native_create_display(EGLNativeDisplayType dpy); +native_create_display(EGLNativeDisplayType dpy, + struct native_event_handler *handler); #endif /* _NATIVE_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native_modeset.h b/src/gallium/state_trackers/egl/common/native_modeset.h new file mode 100644 index 00000000000..71dc3ec860e --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_modeset.h @@ -0,0 +1,87 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _NATIVE_MODESET_H_ +#define _NATIVE_MODESET_H_ + +#include "pipe/p_compiler.h" + +struct native_display; +struct native_surface; +struct native_config; + +struct native_connector { + int dummy; +}; + +struct native_mode { + const char *desc; + int width, height; + int refresh_rate; +}; + +/** + * Mode setting interface of the native display. It exposes the mode setting + * capabilities of the underlying graphics hardware. + */ +struct native_display_modeset { + /** + * Get the available physical connectors and the number of CRTCs. + */ + const struct native_connector **(*get_connectors)(struct native_display *ndpy, + int *num_connectors, + int *num_crtcs); + + /** + * Get the current supported modes of a connector. The returned modes may + * change every time this function is called and those from previous calls + * might become invalid. + */ + const struct native_mode **(*get_modes)(struct native_display *ndpy, + const struct native_connector *nconn, + int *num_modes); + + /** + * Create a scan-out surface. Required unless no config has + * GLX_SCREEN_BIT_MESA set. + */ + struct native_surface *(*create_scanout_surface)(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height); + + /** + * Program the CRTC to output the surface to the given connectors with the + * given mode. When surface is not given, the CRTC is disabled. + * + * This interface does not export a way to query capabilities of the CRTCs. + * The native display usually needs to dynamically map the index to a CRTC + * that supports the given connectors. + */ + boolean (*program)(struct native_display *ndpy, int crtc_idx, + struct native_surface *nsurf, uint x, uint y, + const struct native_connector **nconns, int num_nconns, + const struct native_mode *nmode); +}; + +#endif /* _NATIVE_MODESET_H_ */ diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h index 507a0ec4027..562dd68c150 100644 --- a/src/gallium/state_trackers/egl/common/st_public_tmp.h +++ b/src/gallium/state_trackers/egl/common/st_public_tmp.h @@ -9,7 +9,7 @@ ST_PUBLIC(st_get_framebuffer_surface, int, struct st_f ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture) ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb) ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb) -ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read) +ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read, void *winsys_drawable_handle) ST_PUBLIC(st_get_current, struct st_context *, void) ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence) ST_PUBLIC(st_finish, void, struct st_context *st) diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c index 91cefc538d1..73222408565 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.c +++ b/src/gallium/state_trackers/egl/kms/native_kms.c @@ -55,7 +55,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, templ.format = ksurf->color_format; templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT) - templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; + templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; } /* create textures */ @@ -100,7 +100,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) for (i = 0; i < num_framebuffers; i++) { struct kms_framebuffer *fb; enum native_attachment natt; - unsigned int handle, stride; + struct winsys_handle whandle; uint block_bits; if (i == 0) { @@ -128,13 +128,17 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) /* TODO detect the real value */ fb->is_passive = TRUE; - if (!kdpy->api->local_handle_from_texture(kdpy->api, - kdpy->base.screen, fb->texture, &stride, &handle)) + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_KMS; + + if (!kdpy->base.screen->texture_get_handle(kdpy->base.screen, + fb->texture, &whandle)) return FALSE; block_bits = util_format_get_blocksizebits(ksurf->color_format); err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height, - block_bits, block_bits, stride, handle, &fb->buffer_id); + block_bits, block_bits, whandle.stride, whandle.handle, + &fb->buffer_id); if (err) { fb->buffer_id = 0; return FALSE; @@ -201,6 +205,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf) /* the front/back textures are swapped */ ksurf->sequence_number++; + kdpy->event_handler->invalid_surface(&kdpy->base, + &ksurf->base, ksurf->sequence_number); return TRUE; } @@ -499,7 +505,10 @@ kms_display_get_modes(struct native_display *ndpy, kmode->base.desc = kmode->mode.name; kmode->base.width = kmode->mode.hdisplay; kmode->base.height = kmode->mode.vdisplay; - kmode->base.refresh_rate = kmode->mode.vrefresh / 1000; + kmode->base.refresh_rate = kmode->mode.vrefresh; + /* not all kernels have vrefresh = refresh_rate * 1000 */ + if (kmode->base.refresh_rate > 1000) + kmode->base.refresh_rate = (kmode->base.refresh_rate + 500) / 1000; } nmodes_return = malloc(count * sizeof(*nmodes_return)); @@ -606,9 +615,9 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs) /* always double-buffered */ nconf->mode.doubleBufferMode = TRUE; - format = PIPE_FORMAT_A8R8G8B8_UNORM; + format = PIPE_FORMAT_B8G8R8A8_UNORM; if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) { - format = PIPE_FORMAT_B8G8R8A8_UNORM; + format = PIPE_FORMAT_A8R8G8B8_UNORM; if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) format = PIPE_FORMAT_NONE; } @@ -622,9 +631,9 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs) nconf->mode.alphaBits = 8; nconf->mode.rgbBits = 32; - format = PIPE_FORMAT_S8Z24_UNORM; + format = PIPE_FORMAT_Z24S8_UNORM; if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) { - format = PIPE_FORMAT_Z24S8_UNORM; + format = PIPE_FORMAT_S8Z24_UNORM; if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) format = PIPE_FORMAT_NONE; } @@ -660,6 +669,21 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs) return configs; } +static int +kms_display_get_param(struct native_display *ndpy, + enum native_param_type param) +{ + int val; + + switch (param) { + default: + val = 0; + break; + } + + return val; +} + static void kms_display_destroy(struct native_display *ndpy) { @@ -759,7 +783,9 @@ static struct native_display_modeset kms_display_modeset = { }; static struct native_display * -kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api) +kms_create_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler, + struct drm_api *api) { struct kms_display *kdpy; @@ -767,6 +793,8 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api) if (!kdpy) return NULL; + kdpy->event_handler = event_handler; + kdpy->api = api; if (!kdpy->api) { _eglLog(_EGL_WARNING, "failed to create DRM API"); @@ -802,6 +830,7 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api) } kdpy->base.destroy = kms_display_destroy; + kdpy->base.get_param = kms_display_get_param; kdpy->base.get_configs = kms_display_get_configs; kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface; @@ -842,7 +871,8 @@ native_get_name(void) } struct native_display * -native_create_display(EGLNativeDisplayType dpy) +native_create_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler) { struct native_display *ndpy = NULL; @@ -850,7 +880,7 @@ native_create_display(EGLNativeDisplayType dpy) drm_api = drm_api_create(); if (drm_api) - ndpy = kms_create_display(dpy, drm_api); + ndpy = kms_create_display(dpy, event_handler, drm_api); return ndpy; } diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h index 095186e3cf3..f9cbcb158b5 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.h +++ b/src/gallium/state_trackers/egl/kms/native_kms.h @@ -53,6 +53,8 @@ struct kms_crtc { struct kms_display { struct native_display base; + struct native_event_handler *event_handler; + int fd; struct drm_api *api; drmModeResPtr resources; diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c index 5f2fd412604..98399792311 100644 --- a/src/gallium/state_trackers/egl/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -26,6 +26,7 @@ #include "util/u_math.h" #include "util/u_format.h" #include "util/u_inlines.h" +#include "util/u_hash_table.h" #include "pipe/p_compiler.h" #include "pipe/p_screen.h" #include "pipe/p_context.h" @@ -47,12 +48,18 @@ struct dri2_display { Display *dpy; boolean own_dpy; + struct native_event_handler *event_handler; + struct drm_api *api; struct x11_screen *xscr; int xscr_number; + const char *dri_driver; + int dri_major, dri_minor; struct dri2_config *configs; int num_configs; + + struct util_hash_table *surfaces; }; struct dri2_surface { @@ -62,10 +69,16 @@ struct dri2_surface { enum pipe_format color_format; struct dri2_display *dri2dpy; - struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS]; - boolean have_back, have_fake; + unsigned int server_stamp; + unsigned int client_stamp; int width, height; - unsigned int sequence_number; + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + uint valid_mask; + + boolean have_back, have_fake; + + struct x11_drawable_buffer *last_xbufs; + int last_num_xbufs; }; struct dri2_config { @@ -90,110 +103,103 @@ dri2_config(const struct native_config *nconf) return (struct dri2_config *) nconf; } -static boolean -dri2_surface_flush_frontbuffer(struct native_surface *nsurf) +/** + * Process the buffers returned by the server. + */ +static void +dri2_surface_process_drawable_buffers(struct native_surface *nsurf, + struct x11_drawable_buffer *xbufs, + int num_xbufs) { struct dri2_surface *dri2surf = dri2_surface(nsurf); struct dri2_display *dri2dpy = dri2surf->dri2dpy; + struct pipe_texture templ; + struct winsys_handle whandle; + uint valid_mask; + int i; - /* pbuffer is private */ - if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) - return TRUE; + /* free the old textures */ + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) + pipe_texture_reference(&dri2surf->textures[i], NULL); + dri2surf->valid_mask = 0x0; - /* copy to real front buffer */ - if (dri2surf->have_fake) - x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, - 0, 0, dri2surf->width, dri2surf->height, - DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); + dri2surf->have_back = FALSE; + dri2surf->have_fake = FALSE; - return TRUE; -} + if (!xbufs) + return; -static boolean -dri2_surface_swap_buffers(struct native_surface *nsurf) -{ - struct dri2_surface *dri2surf = dri2_surface(nsurf); - struct dri2_display *dri2dpy = dri2surf->dri2dpy; + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = dri2surf->width; + templ.height0 = dri2surf->height; + templ.depth0 = 1; + templ.format = dri2surf->color_format; + templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; - /* pbuffer is private */ - if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) - return TRUE; + valid_mask = 0x0; + for (i = 0; i < num_xbufs; i++) { + struct x11_drawable_buffer *xbuf = &xbufs[i]; + const char *desc; + enum native_attachment natt; - /* copy to front buffer */ - if (dri2surf->have_back) - x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, - 0, 0, dri2surf->width, dri2surf->height, - DRI2BufferBackLeft, DRI2BufferFrontLeft); + switch (xbuf->attachment) { + case DRI2BufferFrontLeft: + natt = NATIVE_ATTACHMENT_FRONT_LEFT; + desc = "DRI2 Front Buffer"; + break; + case DRI2BufferFakeFrontLeft: + natt = NATIVE_ATTACHMENT_FRONT_LEFT; + desc = "DRI2 Fake Front Buffer"; + dri2surf->have_fake = TRUE; + break; + case DRI2BufferBackLeft: + natt = NATIVE_ATTACHMENT_BACK_LEFT; + desc = "DRI2 Back Buffer"; + dri2surf->have_back = TRUE; + break; + default: + desc = NULL; + break; + } - /* and update fake front buffer */ - if (dri2surf->have_fake) - x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, - 0, 0, dri2surf->width, dri2surf->height, - DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); + if (!desc || dri2surf->textures[natt]) { + if (!desc) + _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment); + else + _eglLog(_EGL_WARNING, "both real and fake front buffers are listed"); + continue; + } - return TRUE; + memset(&whandle, 0, sizeof(whandle)); + whandle.stride = xbuf->pitch; + whandle.handle = xbuf->name; + dri2surf->textures[natt] = dri2dpy->base.screen->texture_from_handle( + dri2dpy->base.screen, &templ, &whandle); + if (dri2surf->textures[natt]) + valid_mask |= 1 << natt; + } + + dri2surf->valid_mask = valid_mask; } -static boolean -dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask, - unsigned int *seq_num, struct pipe_texture **textures, - int *width, int *height) +/** + * Get the buffers from the server. + */ +static void +dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask) { struct dri2_surface *dri2surf = dri2_surface(nsurf); struct dri2_display *dri2dpy = dri2surf->dri2dpy; unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS]; - struct pipe_texture templ; + int num_ins, num_outs, att; struct x11_drawable_buffer *xbufs; - int num_ins, num_outs, att, i; - - if (attachment_mask) { - memset(&templ, 0, sizeof(templ)); - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = dri2surf->width; - templ.height0 = dri2surf->height; - templ.depth0 = 1; - templ.format = dri2surf->color_format; - templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; - - if (textures) - memset(textures, 0, sizeof(*textures) * NUM_NATIVE_ATTACHMENTS); - } - - /* create textures for pbuffer */ - if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) { - struct pipe_screen *screen = dri2dpy->base.screen; - - for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - struct pipe_texture *ptex = dri2surf->pbuffer_textures[att]; - - /* delay the allocation */ - if (!native_attachment_mask_test(attachment_mask, att)) - continue; - - if (!ptex) { - ptex = screen->texture_create(screen, &templ); - dri2surf->pbuffer_textures[att] = ptex; - } - - if (textures) - pipe_texture_reference(&textures[att], ptex); - } - - if (seq_num) - *seq_num = dri2surf->sequence_number; - if (width) - *width = dri2surf->width; - if (height) - *height = dri2surf->height; - - return TRUE; - } /* prepare the attachments */ num_ins = 0; for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - if (native_attachment_mask_test(attachment_mask, att)) { + if (native_attachment_mask_test(buffer_mask, att)) { unsigned int dri2att; switch (att) { @@ -220,79 +226,178 @@ dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask, } } - dri2surf->have_back = FALSE; - dri2surf->have_fake = FALSE; - - /* remember old geometry */ - templ.width0 = dri2surf->width; - templ.height0 = dri2surf->height; - xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable, &dri2surf->width, &dri2surf->height, dri2atts, FALSE, num_ins, &num_outs); - if (!xbufs) - return FALSE; - if (templ.width0 != dri2surf->width || templ.height0 != dri2surf->height) { - /* are there cases where the buffers change and the geometry doesn't? */ - dri2surf->sequence_number++; + /* we should be able to do better... */ + if (xbufs && dri2surf->last_num_xbufs == num_outs && + memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) { + free(xbufs); + dri2surf->client_stamp = dri2surf->server_stamp; + return; + } + + dri2_surface_process_drawable_buffers(&dri2surf->base, xbufs, num_outs); + dri2surf->server_stamp++; + dri2surf->client_stamp = dri2surf->server_stamp; + + if (dri2surf->last_xbufs) + free(dri2surf->last_xbufs); + dri2surf->last_xbufs = xbufs; + dri2surf->last_num_xbufs = num_outs; +} + +/** + * Update the buffers of the surface. This is a slow function due to the + * round-trip to the server. + */ +static boolean +dri2_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + + /* create textures for pbuffer */ + if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) { + struct pipe_screen *screen = dri2dpy->base.screen; + struct pipe_texture templ; + uint new_valid = 0x0; + int att; + + buffer_mask &= ~dri2surf->valid_mask; + if (!buffer_mask) + return TRUE; + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; templ.width0 = dri2surf->width; templ.height0 = dri2surf->height; - } - - for (i = 0; i < num_outs; i++) { - struct x11_drawable_buffer *xbuf = &xbufs[i]; - const char *desc; - enum native_attachment natt; + templ.depth0 = 1; + templ.format = dri2surf->color_format; + templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; - switch (xbuf->attachment) { - case DRI2BufferFrontLeft: - natt = NATIVE_ATTACHMENT_FRONT_LEFT; - desc = "DRI2 Front Buffer"; - break; - case DRI2BufferFakeFrontLeft: - natt = NATIVE_ATTACHMENT_FRONT_LEFT; - desc = "DRI2 Fake Front Buffer"; - dri2surf->have_fake = TRUE; - break; - case DRI2BufferBackLeft: - natt = NATIVE_ATTACHMENT_BACK_LEFT; - desc = "DRI2 Back Buffer"; - dri2surf->have_back = TRUE; - break; - default: - desc = NULL; - break; - } + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + if (native_attachment_mask_test(buffer_mask, att)) { + assert(!dri2surf->textures[att]); - if (!desc || !native_attachment_mask_test(attachment_mask, natt) || - (textures && textures[natt])) { - if (!desc) - _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment); - else if (!native_attachment_mask_test(attachment_mask, natt)) - _eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment); - else - _eglLog(_EGL_WARNING, "both real and fake front buffers are listed"); - continue; - } + dri2surf->textures[att] = screen->texture_create(screen, &templ); + if (!dri2surf->textures[att]) + break; - if (textures) { - struct pipe_texture *ptex = - dri2dpy->api->texture_from_shared_handle(dri2dpy->api, - dri2dpy->base.screen, &templ, - desc, xbuf->pitch, xbuf->name); - if (ptex) { - /* the caller owns the textures */ - textures[natt] = ptex; + new_valid |= 1 << att; + if (new_valid == buffer_mask) + break; } } + dri2surf->valid_mask |= new_valid; + /* no need to update the stamps */ + } + else { + dri2_surface_get_buffers(&dri2surf->base, buffer_mask); + } + + return ((dri2surf->valid_mask & buffer_mask) == buffer_mask); +} + +/** + * Return TRUE if the surface receives DRI2_InvalidateBuffers events. + */ +static INLINE boolean +dri2_surface_receive_events(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + return (dri2surf->dri2dpy->dri_minor >= 3); +} + +static boolean +dri2_surface_flush_frontbuffer(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + + /* pbuffer is private */ + if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) + return TRUE; + + /* copy to real front buffer */ + if (dri2surf->have_fake) + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); + + /* force buffers to be updated in next validation call */ + if (!dri2_surface_receive_events(&dri2surf->base)) { + dri2surf->server_stamp++; + dri2dpy->event_handler->invalid_surface(&dri2dpy->base, + &dri2surf->base, dri2surf->server_stamp); } - free(xbufs); + return TRUE; +} + +static boolean +dri2_surface_swap_buffers(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + + /* pbuffer is private */ + if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) + return TRUE; + + /* copy to front buffer */ + if (dri2surf->have_back) + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferBackLeft, DRI2BufferFrontLeft); + + /* and update fake front buffer */ + if (dri2surf->have_fake) + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); + + /* force buffers to be updated in next validation call */ + if (!dri2_surface_receive_events(&dri2surf->base)) { + dri2surf->server_stamp++; + dri2dpy->event_handler->invalid_surface(&dri2dpy->base, + &dri2surf->base, dri2surf->server_stamp); + } + + return TRUE; +} + +static boolean +dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + + if (dri2surf->server_stamp != dri2surf->client_stamp || + (dri2surf->valid_mask & attachment_mask) != attachment_mask) { + if (!dri2_surface_update_buffers(&dri2surf->base, attachment_mask)) + return FALSE; + } if (seq_num) - *seq_num = dri2surf->sequence_number; + *seq_num = dri2surf->client_stamp; + + if (textures) { + int att; + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + if (native_attachment_mask_test(attachment_mask, att)) { + struct pipe_texture *ptex = dri2surf->textures[att]; + + textures[att] = NULL; + pipe_texture_reference(&textures[att], ptex); + } + } + } + if (width) *width = dri2surf->width; if (height) @@ -320,14 +425,21 @@ dri2_surface_destroy(struct native_surface *nsurf) struct dri2_surface *dri2surf = dri2_surface(nsurf); int i; + if (dri2surf->last_xbufs) + free(dri2surf->last_xbufs); + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { - struct pipe_texture *ptex = dri2surf->pbuffer_textures[i]; + struct pipe_texture *ptex = dri2surf->textures[i]; pipe_texture_reference(&ptex, NULL); } - if (dri2surf->drawable) + if (dri2surf->drawable) { x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr, dri2surf->drawable, FALSE); + + util_hash_table_remove(dri2surf->dri2dpy->surfaces, + (void *) dri2surf->drawable); + } free(dri2surf); } @@ -345,9 +457,6 @@ dri2_display_create_surface(struct native_display *ndpy, if (!dri2surf) return NULL; - if (drawable) - x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE); - dri2surf->dri2dpy = dri2dpy; dri2surf->type = type; dri2surf->drawable = drawable; @@ -359,6 +468,15 @@ dri2_display_create_surface(struct native_display *ndpy, dri2surf->base.validate = dri2_surface_validate; dri2surf->base.wait = dri2_surface_wait; + if (drawable) { + x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE); + /* initialize the geometry */ + dri2_surface_update_buffers(&dri2surf->base, 0x0); + + util_hash_table_set(dri2surf->dri2dpy->surfaces, + (void *) dri2surf->drawable, (void *) &dri2surf->base); + } + return dri2surf; } @@ -409,17 +527,17 @@ choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32]) switch (mode->rgbBits) { case 32: - formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM; + formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; break; case 24: - formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM; formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM; - formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; + formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM; formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM; + formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; break; case 16: - formats[count++] = PIPE_FORMAT_R5G6B5_UNORM; + formats[count++] = PIPE_FORMAT_B5G6R5_UNORM; break; default: break; @@ -440,12 +558,12 @@ choose_depth_stencil_format(const __GLcontextModes *mode, break; case 24: if (mode->stencilBits) { - formats[count++] = PIPE_FORMAT_S8Z24_UNORM; formats[count++] = PIPE_FORMAT_Z24S8_UNORM; + formats[count++] = PIPE_FORMAT_S8Z24_UNORM; } else { - formats[count++] = PIPE_FORMAT_X8Z24_UNORM; formats[count++] = PIPE_FORMAT_Z24X8_UNORM; + formats[count++] = PIPE_FORMAT_X8Z24_UNORM; } break; case 16: @@ -592,6 +710,25 @@ dri2_display_is_pixmap_supported(struct native_display *ndpy, return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth)); } +static int +dri2_display_get_param(struct native_display *ndpy, + enum native_param_type param) +{ + int val; + + switch (param) { + case NATIVE_PARAM_USE_NATIVE_BUFFER: + /* DRI2GetBuffers use the native buffers */ + val = TRUE; + break; + default: + val = 0; + break; + } + + return val; +} + static void dri2_display_destroy(struct native_display *ndpy) { @@ -603,6 +740,9 @@ dri2_display_destroy(struct native_display *ndpy) if (dri2dpy->base.screen) dri2dpy->base.screen->destroy(dri2dpy->base.screen); + if (dri2dpy->surfaces) + util_hash_table_destroy(dri2dpy->surfaces); + if (dri2dpy->xscr) x11_screen_destroy(dri2dpy->xscr); if (dri2dpy->own_dpy) @@ -612,6 +752,27 @@ dri2_display_destroy(struct native_display *ndpy) free(dri2dpy); } +static void +dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable, + void *user_data) +{ + struct native_display *ndpy = (struct native_display* ) user_data; + struct dri2_display *dri2dpy = dri2_display(ndpy); + struct native_surface *nsurf; + struct dri2_surface *dri2surf; + + nsurf = (struct native_surface *) + util_hash_table_get(dri2dpy->surfaces, (void *) drawable); + if (!nsurf) + return; + + dri2surf = dri2_surface(nsurf); + + dri2surf->server_stamp++; + dri2dpy->event_handler->invalid_surface(&dri2dpy->base, + &dri2surf->base, dri2surf->server_stamp); +} + /** * Initialize DRI2 and pipe screen. */ @@ -629,7 +790,17 @@ dri2_display_init_screen(struct native_display *ndpy) return FALSE; } - fd = x11_screen_enable_dri2(dri2dpy->xscr, driver); + dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr, + &dri2dpy->dri_major, &dri2dpy->dri_minor); + if (!dri2dpy->dri_driver || !driver || + strcmp(dri2dpy->dri_driver, driver) != 0) { + _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s", + dri2dpy->dri_driver, dri2dpy->api->name); + return FALSE; + } + + fd = x11_screen_enable_dri2(dri2dpy->xscr, + dri2_display_invalidate_buffers, &dri2dpy->base); if (fd < 0) return FALSE; @@ -644,8 +815,23 @@ dri2_display_init_screen(struct native_display *ndpy) return TRUE; } +static unsigned +dri2_display_hash_table_hash(void *key) +{ + XID drawable = pointer_to_uintptr(key); + return (unsigned) drawable; +} + +static int +dri2_display_hash_table_compare(void *key1, void *key2) +{ + return (key1 - key2); +} + struct native_display * -x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api) +x11_create_dri2_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler, + struct drm_api *api) { struct dri2_display *dri2dpy; @@ -653,12 +839,8 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api) if (!dri2dpy) return NULL; + dri2dpy->event_handler = event_handler; dri2dpy->api = api; - if (!dri2dpy->api) { - _eglLog(_EGL_WARNING, "failed to create DRM API"); - free(dri2dpy); - return NULL; - } dri2dpy->dpy = dpy; if (!dri2dpy->dpy) { @@ -682,7 +864,15 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api) return NULL; } + dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash, + dri2_display_hash_table_compare); + if (!dri2dpy->surfaces) { + dri2_display_destroy(&dri2dpy->base); + return NULL; + } + dri2dpy->base.destroy = dri2_display_destroy; + dri2dpy->base.get_param = dri2_display_get_param; dri2dpy->base.get_configs = dri2_display_get_configs; dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; dri2dpy->base.create_window_surface = dri2_display_create_window_surface; diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c index 8eb542bd827..c6eb17ab1ac 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.c +++ b/src/gallium/state_trackers/egl/x11/native_x11.c @@ -70,7 +70,7 @@ native_create_probe(EGLNativeDisplayType dpy) xscr = x11_screen_create(xdpy, scr); if (xscr) { if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) { - driver_name = x11_screen_probe_dri2(xscr); + driver_name = x11_screen_probe_dri2(xscr, NULL, NULL); if (driver_name) nprobe->data = strdup(driver_name); } @@ -126,7 +126,8 @@ native_get_name(void) } struct native_display * -native_create_display(EGLNativeDisplayType dpy) +native_create_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler) { struct native_display *ndpy = NULL; boolean force_sw; @@ -136,14 +137,14 @@ native_create_display(EGLNativeDisplayType dpy) force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE); if (api && !force_sw) { - ndpy = x11_create_dri2_display(dpy, api); + ndpy = x11_create_dri2_display(dpy, event_handler, api); } if (!ndpy) { EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING; _eglLog(level, "use software fallback"); - ndpy = x11_create_ximage_display(dpy, TRUE); + ndpy = x11_create_ximage_display(dpy, event_handler); } return ndpy; diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h index 622ddac5df6..1566524926a 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.h +++ b/src/gallium/state_trackers/egl/x11/native_x11.h @@ -29,9 +29,12 @@ #include "common/native.h" struct native_display * -x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm); +x11_create_ximage_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler); struct native_display * -x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api); +x11_create_dri2_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler, + struct drm_api *api); #endif /* _NATIVE_X11_H_ */ diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index 92a62f230e0..e0d12acabe8 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -28,17 +28,19 @@ #include <sys/shm.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -#include <X11/extensions/XShm.h> #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_format.h" #include "pipe/p_compiler.h" -#include "util/u_simple_screen.h" #include "util/u_inlines.h" -#include "softpipe/sp_winsys.h" +#include "state_tracker/xlib_sw_winsys.h" +#include "target-helpers/wrap_screen.h" +#include "util/u_debug.h" +#include "softpipe/sp_public.h" +#include "llvmpipe/lp_public.h" +#include "cell/ppu/cell_public.h" #include "egllog.h" -#include "sw_winsys.h" #include "native_x11.h" #include "x11_screen.h" @@ -53,22 +55,18 @@ struct ximage_display { Display *dpy; boolean own_dpy; + struct native_event_handler *event_handler; + struct x11_screen *xscr; int xscr_number; - boolean use_xshm; - - struct pipe_winsys *winsys; struct ximage_config *configs; int num_configs; }; struct ximage_buffer { - XImage *ximage; - struct pipe_texture *texture; - XShmSegmentInfo *shm_info; - boolean xshm_attached; + struct xlib_drawable xdraw; }; struct ximage_surface { @@ -79,11 +77,11 @@ struct ximage_surface { XVisualInfo visual; struct ximage_display *xdpy; + unsigned int server_stamp; + unsigned int client_stamp; int width, height; - GC gc; - struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS]; - unsigned int sequence_number; + uint valid_mask; }; struct ximage_config { @@ -117,18 +115,6 @@ ximage_surface_free_buffer(struct native_surface *nsurf, struct ximage_buffer *xbuf = &xsurf->buffers[which]; pipe_texture_reference(&xbuf->texture, NULL); - - if (xbuf->shm_info) { - if (xbuf->xshm_attached) - XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info); - if (xbuf->shm_info->shmaddr != (void *) -1) - shmdt(xbuf->shm_info->shmaddr); - if (xbuf->shm_info->shmid != -1) - shmctl(xbuf->shm_info->shmid, IPC_RMID, 0); - - xbuf->shm_info->shmaddr = (void *) -1; - xbuf->shm_info->shmid = -1; - } } static boolean @@ -152,40 +138,25 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf, templ.depth0 = 1; templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; - if (xbuf->shm_info) { - struct pipe_buffer *pbuf; - unsigned stride, size; - void *addr = NULL; - - stride = util_format_get_stride(xsurf->color_format, xsurf->width); - /* alignment should depend on visual? */ - stride = align(stride, 4); - size = stride * xsurf->height; - - /* create and attach shm object */ - xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755); - if (xbuf->shm_info->shmid != -1) { - xbuf->shm_info->shmaddr = - shmat(xbuf->shm_info->shmid, NULL, 0); - if (xbuf->shm_info->shmaddr != (void *) -1) { - if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) { - addr = xbuf->shm_info->shmaddr; - xbuf->xshm_attached = TRUE; - } - } - } - - if (addr) { - pbuf = screen->user_buffer_create(screen, addr, size); - if (pbuf) { - xbuf->texture = - screen->texture_blanket(screen, &templ, &stride, pbuf); - pipe_buffer_reference(&pbuf, NULL); - } + if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) { + switch (which) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + case NATIVE_ATTACHMENT_FRONT_RIGHT: + templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + case NATIVE_ATTACHMENT_BACK_RIGHT: + templ.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + break; + default: + break; } } - else { - xbuf->texture = screen->texture_create(screen, &templ); + xbuf->texture = screen->texture_create(screen, &templ); + if (xbuf->texture) { + xbuf->xdraw.visual = xsurf->visual.visual; + xbuf->xdraw.depth = xsurf->visual.depth; + xbuf->xdraw.drawable = xsurf->drawable; } /* clean up the buffer if allocation failed */ @@ -195,6 +166,92 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf, return (xbuf->texture != NULL); } +/** + * Update the geometry of the surface. Return TRUE if the geometry has changed + * since last call. + */ +static boolean +ximage_surface_update_geometry(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + Status ok; + Window root; + int x, y; + unsigned int w, h, border, depth; + boolean updated = FALSE; + + /* pbuffer has fixed geometry */ + if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) + return FALSE; + + ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable, + &root, &x, &y, &w, &h, &border, &depth); + if (ok && (xsurf->width != w || xsurf->height != h)) { + xsurf->width = w; + xsurf->height = h; + + xsurf->server_stamp++; + updated = TRUE; + } + + return updated; +} + +static void +ximage_surface_notify_invalid(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + struct ximage_display *xdpy = xsurf->xdpy; + + xdpy->event_handler->invalid_surface(&xdpy->base, + &xsurf->base, xsurf->server_stamp); +} + +/** + * Update the buffers of the surface. It is a slow function due to the + * round-trip to the server. + */ +static boolean +ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + boolean updated; + uint new_valid; + int att; + + updated = ximage_surface_update_geometry(&xsurf->base); + if (updated) { + /* all buffers become invalid */ + xsurf->valid_mask = 0x0; + } + else { + buffer_mask &= ~xsurf->valid_mask; + /* all requested buffers are valid */ + if (!buffer_mask) { + xsurf->client_stamp = xsurf->server_stamp; + return TRUE; + } + } + + new_valid = 0x0; + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + if (native_attachment_mask_test(buffer_mask, att)) { + /* reallocate the texture */ + if (!ximage_surface_alloc_buffer(&xsurf->base, att)) + break; + + new_valid |= (1 << att); + if (buffer_mask == new_valid) + break; + } + } + + xsurf->valid_mask |= new_valid; + xsurf->client_stamp = xsurf->server_stamp; + + return (new_valid == buffer_mask); +} + static boolean ximage_surface_draw_buffer(struct native_surface *nsurf, enum native_attachment which) @@ -202,43 +259,22 @@ ximage_surface_draw_buffer(struct native_surface *nsurf, struct ximage_surface *xsurf = ximage_surface(nsurf); struct ximage_buffer *xbuf = &xsurf->buffers[which]; struct pipe_screen *screen = xsurf->xdpy->base.screen; - struct pipe_transfer *transfer; + struct pipe_surface *psurf; if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) return TRUE; - assert(xsurf->drawable && xbuf->ximage && xbuf->texture); + assert(xsurf->drawable && xbuf->texture); - transfer = screen->get_tex_transfer(screen, xbuf->texture, - 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height); - if (!transfer) + /* what's the cost of surface creation? */ + psurf = screen->get_tex_surface(screen, + xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ); + if (!psurf) return FALSE; - xbuf->ximage->bytes_per_line = transfer->stride; - xbuf->ximage->data = screen->transfer_map(screen, transfer); - if (!xbuf->ximage->data) { - screen->tex_transfer_destroy(transfer); - return FALSE; - } - - - if (xbuf->shm_info) - XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc, - xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False); - else - XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc, - xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height); - - xbuf->ximage->data = NULL; - screen->transfer_unmap(screen, transfer); + screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw); - /* - * softpipe allows the pipe transfer to be re-used, but we don't want to - * rely on that behavior. - */ - screen->tex_transfer_destroy(transfer); - - XSync(xsurf->xdpy->dpy, FALSE); + pipe_surface_reference(&psurf, NULL); return TRUE; } @@ -246,7 +282,16 @@ ximage_surface_draw_buffer(struct native_surface *nsurf, static boolean ximage_surface_flush_frontbuffer(struct native_surface *nsurf) { - return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); + struct ximage_surface *xsurf = ximage_surface(nsurf); + boolean ret; + + ret = ximage_surface_draw_buffer(&xsurf->base, + NATIVE_ATTACHMENT_FRONT_LEFT); + /* force buffers to be updated in next validation call */ + xsurf->server_stamp++; + ximage_surface_notify_invalid(&xsurf->base); + + return ret; } static boolean @@ -254,44 +299,26 @@ ximage_surface_swap_buffers(struct native_surface *nsurf) { struct ximage_surface *xsurf = ximage_surface(nsurf); struct ximage_buffer *xfront, *xback, xtmp; + boolean ret; + + /* display the back buffer first */ + ret = ximage_surface_draw_buffer(&xsurf->base, + NATIVE_ATTACHMENT_BACK_LEFT); + /* force buffers to be updated in next validation call */ + xsurf->server_stamp++; + ximage_surface_notify_invalid(&xsurf->base); xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT]; xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT]; - /* draw the back buffer directly if there is no front buffer */ - if (!xfront->texture) - return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT); - - /* swap the buffers */ - xtmp = *xfront; - *xfront = *xback; - *xback = xtmp; - - /* the front/back textures are swapped */ - xsurf->sequence_number++; - - return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); -} - -static void -ximage_surface_update_geometry(struct native_surface *nsurf) -{ - struct ximage_surface *xsurf = ximage_surface(nsurf); - Status ok; - Window root; - int x, y; - unsigned int w, h, border, depth; - - /* pbuffer has fixed geometry */ - if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) - return; - - ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable, - &root, &x, &y, &w, &h, &border, &depth); - if (ok) { - xsurf->width = w; - xsurf->height = h; + /* skip swapping unless there is a front buffer */ + if (xfront->texture) { + xtmp = *xfront; + *xfront = *xback; + *xback = xtmp; } + + return ret; } static boolean @@ -300,44 +327,28 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, int *width, int *height) { struct ximage_surface *xsurf = ximage_surface(nsurf); - boolean new_buffers = FALSE; - int att; - ximage_surface_update_geometry(&xsurf->base); + if (xsurf->client_stamp != xsurf->server_stamp || + (xsurf->valid_mask & attachment_mask) != attachment_mask) { + if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask)) + return FALSE; + } - for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { - struct ximage_buffer *xbuf = &xsurf->buffers[att]; - - /* delay the allocation */ - if (!native_attachment_mask_test(attachment_mask, att)) - continue; - - /* reallocate the texture */ - if (!xbuf->texture || - xsurf->width != xbuf->texture->width0 || - xsurf->height != xbuf->texture->height0) { - new_buffers = TRUE; - if (ximage_surface_alloc_buffer(&xsurf->base, att)) { - /* update ximage */ - if (xbuf->ximage) { - xbuf->ximage->width = xsurf->width; - xbuf->ximage->height = xsurf->height; - } - } - } + if (seq_num) + *seq_num = xsurf->client_stamp; - if (textures) { - textures[att] = NULL; - pipe_texture_reference(&textures[att], xbuf->texture); + if (textures) { + int att; + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + if (native_attachment_mask_test(attachment_mask, att)) { + struct ximage_buffer *xbuf = &xsurf->buffers[att]; + + textures[att] = NULL; + pipe_texture_reference(&textures[att], xbuf->texture); + } } } - /* increase the sequence number so that caller knows */ - if (new_buffers) - xsurf->sequence_number++; - - if (seq_num) - *seq_num = xsurf->sequence_number; if (width) *width = xsurf->width; if (height) @@ -360,18 +371,9 @@ ximage_surface_destroy(struct native_surface *nsurf) struct ximage_surface *xsurf = ximage_surface(nsurf); int i; - for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { - struct ximage_buffer *xbuf = &xsurf->buffers[i]; + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) ximage_surface_free_buffer(&xsurf->base, i); - /* xbuf->shm_info is owned by xbuf->ximage? */ - if (xbuf->ximage) { - XDestroyImage(xbuf->ximage); - xbuf->ximage = NULL; - } - } - if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) - XFreeGC(xsurf->xdpy->dpy, xsurf->gc); free(xsurf); } @@ -384,7 +386,6 @@ ximage_display_create_surface(struct native_display *ndpy, struct ximage_display *xdpy = ximage_display(ndpy); struct ximage_config *xconf = ximage_config(nconf); struct ximage_surface *xsurf; - int i; xsurf = CALLOC_STRUCT(ximage_surface); if (!xsurf) @@ -398,49 +399,8 @@ ximage_display_create_surface(struct native_display *ndpy, if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) { xsurf->drawable = drawable; xsurf->visual = *xconf->visual; - - xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL); - if (!xsurf->gc) { - free(xsurf); - return NULL; - } - - for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { - struct ximage_buffer *xbuf = &xsurf->buffers[i]; - - if (xdpy->use_xshm) { - xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info)); - if (xbuf->shm_info) { - /* initialize shm info */ - xbuf->shm_info->shmid = -1; - xbuf->shm_info->shmaddr = (void *) -1; - xbuf->shm_info->readOnly = TRUE; - - xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy, - xsurf->visual.visual, - xsurf->visual.depth, - ZPixmap, NULL, - xbuf->shm_info, - 0, 0); - } - } - else { - xbuf->ximage = XCreateImage(xsurf->xdpy->dpy, - xsurf->visual.visual, - xsurf->visual.depth, - ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 8, /* bitmap_pad */ - 0); /* bytes_per_line */ - } - - if (!xbuf->ximage) { - XFreeGC(xdpy->dpy, xsurf->gc); - free(xsurf); - return NULL; - } - } + /* initialize the geometry */ + ximage_surface_update_buffers(&xsurf->base, 0x0); } xsurf->base.destroy = ximage_surface_destroy; @@ -499,13 +459,13 @@ choose_format(const XVisualInfo *vinfo) /* TODO elaborate the formats */ switch (vinfo->depth) { case 32: - fmt = PIPE_FORMAT_A8R8G8B8_UNORM; + fmt = PIPE_FORMAT_B8G8R8A8_UNORM; break; case 24: - fmt = PIPE_FORMAT_X8R8G8B8_UNORM; + fmt = PIPE_FORMAT_B8G8R8X8_UNORM; break; case 16: - fmt = PIPE_FORMAT_R5G6B5_UNORM; + fmt = PIPE_FORMAT_B5G6R5_UNORM; break; default: fmt = PIPE_FORMAT_NONE; @@ -558,8 +518,8 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs) xconf->base.stencil_format = PIPE_FORMAT_NONE; /* create the second config with depth/stencil buffer */ if (j == 1) { - xconf->base.depth_format = PIPE_FORMAT_S8Z24_UNORM; - xconf->base.stencil_format = PIPE_FORMAT_S8Z24_UNORM; + xconf->base.depth_format = PIPE_FORMAT_Z24S8_UNORM; + xconf->base.stencil_format = PIPE_FORMAT_Z24S8_UNORM; mode->depthBits = 24; mode->stencilBits = 8; mode->haveDepthBuffer = TRUE; @@ -607,13 +567,13 @@ ximage_display_is_pixmap_supported(struct native_display *ndpy, depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix); switch (depth) { case 32: - fmt = PIPE_FORMAT_A8R8G8B8_UNORM; + fmt = PIPE_FORMAT_B8G8R8A8_UNORM; break; case 24: - fmt = PIPE_FORMAT_X8R8G8B8_UNORM; + fmt = PIPE_FORMAT_B8G8R8X8_UNORM; break; case 16: - fmt = PIPE_FORMAT_R5G6B5_UNORM; + fmt = PIPE_FORMAT_B5G6R5_UNORM; break; default: fmt = PIPE_FORMAT_NONE; @@ -623,6 +583,25 @@ ximage_display_is_pixmap_supported(struct native_display *ndpy, return (fmt == nconf->color_format); } +static int +ximage_display_get_param(struct native_display *ndpy, + enum native_param_type param) +{ + int val; + + switch (param) { + case NATIVE_PARAM_USE_NATIVE_BUFFER: + /* private buffers are allocated */ + val = FALSE; + break; + default: + val = 0; + break; + } + + return val; +} + static void ximage_display_destroy(struct native_display *ndpy) { @@ -632,7 +611,6 @@ ximage_display_destroy(struct native_display *ndpy) free(xdpy->configs); xdpy->base.screen->destroy(xdpy->base.screen); - free(xdpy->winsys); x11_screen_destroy(xdpy->xscr); if (xdpy->own_dpy) @@ -640,8 +618,63 @@ ximage_display_destroy(struct native_display *ndpy) free(xdpy); } + +/* Helper function to build a subset of a driver stack consisting of + * one of the software rasterizers (cell, llvmpipe, softpipe) and the + * xlib winsys. + * + * This function could be shared, but currently causes headaches for + * the build systems, particularly scons if we try. + * + * Long term, want to avoid having global #defines for things like + * GALLIUM_LLVMPIPE, GALLIUM_CELL, etc. Scons already eliminates + * those #defines, so things that are painful for it now are likely to + * be painful for other build systems in the future. + */ +static struct pipe_screen * +swrast_xlib_create_screen( Display *display ) +{ + struct sw_winsys *winsys; + struct pipe_screen *screen = NULL; + + /* Create the underlying winsys, which performs presents to Xlib + * drawables: + */ + winsys = xlib_create_sw_winsys( display ); + if (winsys == NULL) + return NULL; + + /* Create a software rasterizer on top of that winsys. Use + * llvmpipe if it is available. + */ +#if defined(GALLIUM_LLVMPIPE) + if (screen == NULL && + !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE)) + screen = llvmpipe_create_screen( winsys ); +#endif + + if (screen == NULL) + screen = softpipe_create_screen( winsys ); + + if (screen == NULL) + goto fail; + + /* Inject any wrapping layers we want to here: + */ + return gallium_wrap_screen( screen ); + +fail: + if (winsys) + winsys->destroy( winsys ); + + return NULL; +} + + + struct native_display * -x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm) +x11_create_ximage_display(EGLNativeDisplayType dpy, + struct native_event_handler *event_handler) { struct ximage_display *xdpy; @@ -659,6 +692,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm) xdpy->own_dpy = TRUE; } + xdpy->event_handler = event_handler; + xdpy->xscr_number = DefaultScreen(xdpy->dpy); xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number); if (!xdpy->xscr) { @@ -666,13 +701,10 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm) return NULL; } - xdpy->use_xshm = - (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM)); - - xdpy->winsys = create_sw_winsys(); - xdpy->base.screen = softpipe_create_screen(xdpy->winsys); + xdpy->base.screen = swrast_xlib_create_screen(xdpy->dpy); xdpy->base.destroy = ximage_display_destroy; + xdpy->base.get_param = ximage_display_get_param; xdpy->base.get_configs = ximage_display_get_configs; xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported; diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c deleted file mode 100644 index 33328aadf26..00000000000 --- a/src/gallium/state_trackers/egl/x11/sw_winsys.c +++ /dev/null @@ -1,231 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Totally software-based winsys layer. - * Note that the one winsys function that we can't implement here - * is flush_frontbuffer(). - * Whoever uses this code will have to provide that. - * - * Authors: Brian Paul - */ - - -#include "util/u_simple_screen.h" -#include "pipe/p_state.h" -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_math.h" -#include "util/u_memory.h" - -#include "sw_winsys.h" - - - -/** Subclass of pipe_winsys */ -struct sw_pipe_winsys -{ - struct pipe_winsys Base; - /* no extra fields for now */ -}; - - -/** subclass of pipe_buffer */ -struct sw_pipe_buffer -{ - struct pipe_buffer Base; - boolean UserBuffer; /** Is this a user-space buffer? */ - void *Data; - void *Mapped; -}; - - -/** cast wrapper */ -static INLINE struct sw_pipe_buffer * -sw_pipe_buffer(struct pipe_buffer *b) -{ - return (struct sw_pipe_buffer *) b; -} - - -static const char * -get_name(struct pipe_winsys *pws) -{ - return "software"; -} - - -/** Create new pipe_buffer and allocate storage of given size */ -static struct pipe_buffer * -buffer_create(struct pipe_winsys *pws, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer); - if (!buffer) - return NULL; - - pipe_reference_init(&buffer->Base.reference, 1); - buffer->Base.alignment = alignment; - buffer->Base.usage = usage; - buffer->Base.size = size; - - /* align to 16-byte multiple for Cell */ - buffer->Data = align_malloc(size, MAX2(alignment, 16)); - - return &buffer->Base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) -{ - struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer); - if (!buffer) - return NULL; - - pipe_reference_init(&buffer->Base.reference, 1); - buffer->Base.size = bytes; - buffer->UserBuffer = TRUE; - buffer->Data = ptr; - - return &buffer->Base; -} - - -static void * -buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags) -{ - struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); - buffer->Mapped = buffer->Data; - return buffer->Mapped; -} - - -static void -buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) -{ - struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); - buffer->Mapped = NULL; -} - - -static void -buffer_destroy(struct pipe_buffer *buf) -{ - struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); - - if (buffer->Data && !buffer->UserBuffer) { - align_free(buffer->Data); - buffer->Data = NULL; - } - - free(buffer); -} - - -static struct pipe_buffer * -surface_buffer_create(struct pipe_winsys *winsys, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride) -{ - const unsigned alignment = 64; - unsigned nblocksy; - - nblocksy = util_format_get_nblocksy(format, height); - *stride = align(util_format_get_stride(format, width), alignment); - - return winsys->buffer_create(winsys, alignment, - usage, - *stride * nblocksy); -} - - -static void -fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ - /* no-op */ -} - - -static int -fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - /* no-op */ - return 0; -} - - -static int -fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, - unsigned flag) -{ - /* no-op */ - return 0; -} - - -/** - * Create/return a new pipe_winsys object. - */ -struct pipe_winsys * -create_sw_winsys(void) -{ - struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys); - if (!ws) - return NULL; - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - */ - ws->Base.buffer_create = buffer_create; - ws->Base.user_buffer_create = user_buffer_create; - ws->Base.buffer_map = buffer_map; - ws->Base.buffer_unmap = buffer_unmap; - ws->Base.buffer_destroy = buffer_destroy; - - ws->Base.surface_buffer_create = surface_buffer_create; - - ws->Base.fence_reference = fence_reference; - ws->Base.fence_signalled = fence_signalled; - ws->Base.fence_finish = fence_finish; - - ws->Base.flush_frontbuffer = NULL; /* not implemented here! */ - - ws->Base.get_name = get_name; - - return &ws->Base; -} diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.h b/src/gallium/state_trackers/egl/x11/sw_winsys.h deleted file mode 100644 index f96c5a14b0a..00000000000 --- a/src/gallium/state_trackers/egl/x11/sw_winsys.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef SW_WINSYS_H -#define SW_WINSYS_H - - -struct pipe_winsys; - - -extern struct pipe_winsys * -create_sw_winsys(void); - - -#endif /* SW_WINSYS_H */ diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c index d72bfc99d3e..f4096114844 100644 --- a/src/gallium/state_trackers/egl/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl/x11/x11_screen.c @@ -39,6 +39,9 @@ #include "glxinit.h" struct x11_screen { + /* dummy base class */ + struct __GLXDRIdisplayRec base; + Display *dpy; int number; @@ -53,6 +56,9 @@ struct x11_screen { char *dri_device; int dri_fd; + x11_drawable_invalidate_buffers dri_invalidate_buffers; + void *dri_user_data; + XVisualInfo *visuals; int num_visuals; @@ -98,6 +104,8 @@ x11_screen_destroy(struct x11_screen *xscr) Xfree(xscr->dri_device); /* xscr->glx_dpy will be destroyed with the X display */ + if (xscr->glx_dpy) + xscr->glx_dpy->dri2Display = NULL; if (xscr->visuals) XFree(xscr->visuals); @@ -247,24 +255,25 @@ x11_screen_get_glx_visuals(struct x11_screen *xscr) : NULL; } -static boolean -x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver) -{ - return (strcmp(xscr->dri_driver, driver) == 0); -} - /** * Probe the screen for the DRI2 driver name. */ const char * -x11_screen_probe_dri2(struct x11_screen *xscr) +x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor) { + if (!x11_screen_init_dri2(xscr)) + return NULL; + /* get the driver name and the device name */ if (!xscr->dri_driver) { if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number), &xscr->dri_driver, &xscr->dri_device)) xscr->dri_driver = xscr->dri_device = NULL; } + if (major) + *major = xscr->dri_major; + if (minor) + *minor = xscr->dri_minor; return xscr->dri_driver; } @@ -274,21 +283,17 @@ x11_screen_probe_dri2(struct x11_screen *xscr) * descriptor will be closed automatically when the screen is destoryed. */ int -x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver) +x11_screen_enable_dri2(struct x11_screen *xscr, + x11_drawable_invalidate_buffers invalidate_buffers, + void *user_data) { if (xscr->dri_fd < 0) { int fd; drm_magic_t magic; /* get the driver name and the device name first */ - if (!x11_screen_probe_dri2(xscr)) - return -1; - - if (!x11_screen_is_driver_equal(xscr, driver)) { - _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s", - xscr->dri_driver, driver); + if (!x11_screen_probe_dri2(xscr, NULL, NULL)) return -1; - } fd = open(xscr->dri_device, O_RDWR); if (fd < 0) { @@ -310,6 +315,22 @@ x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver) return -1; } + if (!x11_screen_init_glx(xscr)) { + _eglLog(_EGL_WARNING, "failed to initialize GLX"); + close(fd); + return -1; + } + if (xscr->glx_dpy->dri2Display) { + _eglLog(_EGL_WARNING, + "display is already managed by another x11 screen"); + close(fd); + return -1; + } + + xscr->glx_dpy->dri2Display = (__GLXDRIdisplay *) xscr; + xscr->dri_invalidate_buffers = invalidate_buffers; + xscr->dri_user_data = user_data; + xscr->dri_fd = fd; } @@ -451,3 +472,20 @@ x11_context_modes_count(const __GLcontextModes *modes) count++; return count; } + +/** + * This is called from src/glx/dri2.c. + */ +void +dri2InvalidateBuffers(Display *dpy, XID drawable) +{ + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + struct x11_screen *xscr = NULL; + + if (priv && priv->dri2Display) + xscr = (struct x11_screen *) priv->dri2Display; + if (!xscr || !xscr->dri_invalidate_buffers) + return; + + xscr->dri_invalidate_buffers(xscr, drawable, xscr->dri_user_data); +} diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h index 5432858ac3e..37e8d5a40e6 100644 --- a/src/gallium/state_trackers/egl/x11/x11_screen.h +++ b/src/gallium/state_trackers/egl/x11/x11_screen.h @@ -48,6 +48,10 @@ struct x11_drawable_buffer { struct x11_screen; +typedef void (*x11_drawable_invalidate_buffers)(struct x11_screen *xscr, + Drawable drawable, + void *user_data); + struct x11_screen * x11_screen_create(Display *dpy, int screen); @@ -71,10 +75,12 @@ const __GLcontextModes * x11_screen_get_glx_visuals(struct x11_screen *xscr); const char * -x11_screen_probe_dri2(struct x11_screen *xscr); +x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor); int -x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver); +x11_screen_enable_dri2(struct x11_screen *xscr, + x11_drawable_invalidate_buffers invalidate_buffers, + void *user_data); __GLcontextModes * x11_context_modes_create(unsigned count); diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript index fa96df357d5..bb202351509 100644 --- a/src/gallium/state_trackers/glx/xlib/SConscript +++ b/src/gallium/state_trackers/glx/xlib/SConscript @@ -13,8 +13,6 @@ if env['platform'] == 'linux' \ '#/src/mesa/main', ]) - env.Append(CPPDEFINES = ['USE_XSHM']) - st_xlib = env.ConvenienceLibrary( target = 'st_xlib', source = [ diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c index 3caf56e924b..24545858500 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_api.c +++ b/src/gallium/state_trackers/glx/xlib/glx_api.c @@ -280,7 +280,7 @@ default_depth_bits(void) int zBits; const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); if (zEnv) - zBits = _mesa_atoi(zEnv); + zBits = atoi(zEnv); else zBits = DEFAULT_SOFTWARE_DEPTH_BITS; return zBits; @@ -292,7 +292,7 @@ default_alpha_bits(void) int aBits; const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); if (aEnv) - aBits = _mesa_atoi(aEnv); + aBits = atoi(aEnv); else aBits = 0; return aBits; @@ -442,17 +442,17 @@ get_env_visual(Display *dpy, int scr, const char *varname) return NULL; } - _mesa_strncpy( value, _mesa_getenv(varname), 100 ); + strncpy( value, _mesa_getenv(varname), 100 ); value[99] = 0; sscanf( value, "%s %d", type, &depth ); - if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor; - else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor; - else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor; - else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor; - else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale; - else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray; + if (strcmp(type,"TrueColor")==0) xclass = TrueColor; + else if (strcmp(type,"DirectColor")==0) xclass = DirectColor; + else if (strcmp(type,"PseudoColor")==0) xclass = PseudoColor; + else if (strcmp(type,"StaticColor")==0) xclass = StaticColor; + else if (strcmp(type,"GrayScale")==0) xclass = GrayScale; + else if (strcmp(type,"StaticGray")==0) xclass = StaticGray; if (xclass>-1 && depth>0) { vis = get_visual( dpy, scr, depth, xclass ); @@ -689,6 +689,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) int desiredVisualID = -1; int numAux = 0; + xmesa_init( dpy ); + parselist = list; while (*parselist) { @@ -941,9 +943,6 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) /* give the visual some useful GLX attributes */ double_flag = GL_TRUE; rgb_flag = GL_TRUE; - depth_size = default_depth_bits(); - stencil_size = STENCIL_BITS; - /* XXX accum??? */ } } else if (level==0) { @@ -1018,9 +1017,9 @@ glXChooseVisual( Display *dpy, int screen, int *list ) xmvis = choose_visual(dpy, screen, list, GL_FALSE); if (xmvis) { /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo)); if (xmvis->vishandle) { - _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); } return xmvis->vishandle; } @@ -1055,7 +1054,7 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo, xmvis = create_glx_visual( dpy, visinfo ); if (!xmvis) { /* unusable visual */ - _mesa_free(glxCtx); + free(glxCtx); return NULL; } } @@ -1063,7 +1062,7 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo, glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); + free(glxCtx); return NULL; } @@ -1336,7 +1335,7 @@ glXDestroyContext( Display *dpy, GLXContext ctx ) MakeCurrent_PrevReadBuffer = 0; XMesaDestroyContext( glxCtx->xmesaContext ); XMesaGarbageCollect(); - _mesa_free(glxCtx); + free(glxCtx); } @@ -1679,8 +1678,8 @@ PUBLIC const char * glXQueryServerString( Display *dpy, int screen, int name ) { static char version[1000]; - _mesa_sprintf(version, "%d.%d %s", - SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); + sprintf(version, "%d.%d %s", + SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); (void) dpy; (void) screen; @@ -1704,8 +1703,8 @@ PUBLIC const char * glXGetClientString( Display *dpy, int name ) { static char version[1000]; - _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, - CLIENT_MINOR_VERSION, MESA_GLX_VERSION); + sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, + CLIENT_MINOR_VERSION, MESA_GLX_VERSION); (void) dpy; @@ -1755,7 +1754,7 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements ) visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); if (*nelements > 0) { XMesaVisual *results; - results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); + results = (XMesaVisual *) malloc(*nelements * sizeof(XMesaVisual)); if (!results) { *nelements = 0; return NULL; @@ -1782,7 +1781,7 @@ glXChooseFBConfig( Display *dpy, int screen, xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); if (xmvis) { - GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); + GLXFBConfig *config = (GLXFBConfig *) malloc(sizeof(XMesaVisual)); if (!config) { *nitems = 0; return NULL; @@ -1807,9 +1806,9 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) return xmvis->vishandle; #else /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo)); if (xmvis->vishandle) { - _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); } return xmvis->vishandle; #endif @@ -2112,7 +2111,7 @@ glXCreateNewContext( Display *dpy, GLXFBConfig config, glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); + free(glxCtx); return NULL; } @@ -2332,7 +2331,7 @@ glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_ glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - _mesa_free(glxCtx); + free(glxCtx); return NULL; } diff --git a/src/gallium/state_trackers/glx/xlib/glx_usefont.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c index e502198b204..8903b0e6cbd 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_usefont.c +++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c @@ -343,7 +343,7 @@ glXUseXFont(Font font, int first, int count, int listbase) glNewList(list, GL_COMPILE); if (valid && (bm_width > 0) && (bm_height > 0)) { - MEMSET(bm, '\0', bm_width * bm_height); + memset(bm, '\0', bm_width * bm_height); fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); glBitmap(width, height, x0, y0, dx, dy, bm); diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index fb314f3b528..f4d7133d2ff 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -35,10 +35,6 @@ * corner of the window. Therefore, most drawing functions in this * file have to flip Y coordinates. * - * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile - * in support for the MIT Shared Memory extension. If enabled, when you - * use an Ximage for the back buffer in double buffered mode, the "swap" - * operation will be faster. You must also link with -lXext. * * Byte swapping: If the Mesa host and the X display use a different * byte order then there's some trickiness to be aware of when using @@ -67,11 +63,7 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" -#include "trace/tr_screen.h" -#include "trace/tr_context.h" -#include "trace/tr_texture.h" - -#include "xm_winsys.h" +#include "xm_public.h" #include <GL/glx.h> @@ -91,7 +83,6 @@ void xmesa_set_driver( const struct xm_driver *templ ) */ pipe_mutex _xmesa_lock; -static struct pipe_screen *_screen = NULL; static struct pipe_screen *screen = NULL; @@ -111,41 +102,6 @@ static int host_byte_order( void ) } -/** - * Check if the X Shared Memory extension is available. - * Return: 0 = not available - * 1 = shared XImage support available - * 2 = shared Pixmap support available also - */ -int xmesa_check_for_xshm( Display *display ) -{ -#if defined(USE_XSHM) - int major, minor, ignore; - Bool pixmaps; - - if (getenv("SP_NO_RAST")) - return 0; - - if (getenv("MESA_NOSHM")) { - return 0; - } - - if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { - if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { - return (pixmaps==True) ? 2 : 1; - } - else { - return 0; - } - } - else { - return 0; - } -#else - /* No XSHM support */ - return 0; -#endif -} /** @@ -175,7 +131,7 @@ bits_per_pixel( XMesaVisual xmv ) /* grab the bits/pixel value */ bitsPerPixel = img->bits_per_pixel; /* free the XImage */ - _mesa_free( img->data ); + free( img->data ); img->data = NULL; XDestroyImage( img ); return bitsPerPixel; @@ -242,7 +198,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b, pipe_mutex_lock(_xmesa_lock); XSync(b->xm_visual->display, 0); /* added for Chromium */ - stat = get_drawable_size(dpy, b->drawable, width, height); + stat = get_drawable_size(dpy, b->ws.drawable, width, height); pipe_mutex_unlock(_xmesa_lock); if (!stat) { @@ -274,10 +230,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; + return PIPE_FORMAT_R8G8B8A8_UNORM; } else { - return PIPE_FORMAT_R8G8B8A8_UNORM; + return PIPE_FORMAT_A8B8G8R8_UNORM; } } else if ( GET_REDMASK(v) == 0xff0000 @@ -286,10 +242,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_B8G8R8A8_UNORM; } else { - return PIPE_FORMAT_B8G8R8A8_UNORM; + return PIPE_FORMAT_A8R8G8B8_UNORM; } } else if ( GET_REDMASK(v) == 0x0000ff00 @@ -298,10 +254,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return PIPE_FORMAT_B8G8R8A8_UNORM; + return PIPE_FORMAT_A8R8G8B8_UNORM; } else { - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_B8G8R8A8_UNORM; } } else if ( GET_REDMASK(v) == 0xf800 @@ -310,7 +266,7 @@ choose_pixel_format(XMesaVisual v) && native_byte_order && v->BitsPerPixel == 16) { /* 5-6-5 RGB */ - return PIPE_FORMAT_R5G6B5_UNORM; + return PIPE_FORMAT_B5G6R5_UNORM; } assert(0); @@ -319,6 +275,51 @@ choose_pixel_format(XMesaVisual v) +/** + * Query the default gallium screen for a Z/Stencil format that + * at least matches the given depthBits and stencilBits. + */ +static void +xmesa_choose_z_stencil_format(int depthBits, int stencilBits, + enum pipe_format *depthFormat, + enum pipe_format *stencilFormat) +{ + const enum pipe_texture_target target = PIPE_TEXTURE_2D; + const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE | + PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO); + static enum pipe_format formats[] = { + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z32_UNORM + }; + int i; + + assert(screen); + + *depthFormat = *stencilFormat = PIPE_FORMAT_NONE; + + /* search for supported format */ + for (i = 0; i < Elements(formats); i++) { + if (screen->is_format_supported(screen, formats[i], + target, tex_usage, geom_flags)) { + *depthFormat = formats[i]; + break; + } + } + + if (stencilBits) { + *stencilFormat = *depthFormat; + } + + /* XXX we should check that he chosen format has at least as many bits + * as what was requested. + */ +} + + + /**********************************************************************/ /***** Linked list of XMesaBuffers *****/ /**********************************************************************/ @@ -352,7 +353,9 @@ create_xmesa_buffer(Drawable d, BufferType type, if (!b) return NULL; - b->drawable = d; + b->ws.drawable = d; + b->ws.visual = vis->visinfo->visual; + b->ws.depth = vis->visinfo->depth; b->xm_visual = vis; b->type = type; @@ -361,34 +364,9 @@ create_xmesa_buffer(Drawable d, BufferType type, /* determine PIPE_FORMATs for buffers */ colorFormat = choose_pixel_format(vis); - if (vis->mesa_visual.depthBits == 0) - depthFormat = PIPE_FORMAT_NONE; -#ifdef GALLIUM_CELL /* XXX temporary for Cell! */ - else - depthFormat = PIPE_FORMAT_S8Z24_UNORM; -#else - else if (vis->mesa_visual.depthBits <= 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (vis->mesa_visual.depthBits <= 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_Z32_UNORM; -#endif - - if (vis->mesa_visual.stencilBits == 8) { - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) - stencilFormat = depthFormat; - else - stencilFormat = PIPE_FORMAT_S8_UNORM; - } - else { - /* no stencil */ - stencilFormat = PIPE_FORMAT_NONE; - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) { - /* use 24-bit Z, undefined stencil channel */ - depthFormat = PIPE_FORMAT_X8Z24_UNORM; - } - } + xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits, + vis->mesa_visual.stencilBits, + &depthFormat, &stencilFormat); get_drawable_size(vis->display, d, &width, &height); @@ -402,18 +380,6 @@ create_xmesa_buffer(Drawable d, BufferType type, (void *) b); fb = &b->stfb->Base; - /* - * Create scratch XImage for xmesa_display_surface() - */ - b->tempImage = XCreateImage(vis->display, - vis->visinfo->visual, - vis->visinfo->depth, - ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 32, /* bitmap_pad */ - 0); /* bytes_per_line */ - /* GLX_EXT_texture_from_pixmap */ b->TextureTarget = 0; b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; @@ -470,16 +436,11 @@ xmesa_free_buffer(XMesaBuffer buffer) /* Since the X window for the XMesaBuffer is going away, we don't * want to dereference this pointer in the future. */ - b->drawable = 0; - - buffer->tempImage->data = NULL; - XDestroyImage(buffer->tempImage); + b->ws.drawable = 0; /* Unreference. If count = zero we'll really delete the buffer */ _mesa_reference_framebuffer(&fb, NULL); - XFreeGC(b->xm_visual->display, b->gc); - free(buffer); return; @@ -550,25 +511,10 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, * reports bugs. */ if (_mesa_getenv("MESA_INFO")) { - _mesa_printf("X/Mesa visual = %p\n", (void *) v); - _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); - _mesa_printf("X/Mesa depth = %d\n", v->visinfo->depth); - _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); - } - - if (b && window) { - /* these should have been set in create_xmesa_buffer */ - ASSERT(b->drawable == window); - - /* Setup for single/double buffering */ - if (v->mesa_visual.doubleBufferMode) { - /* Double buffered */ - b->shm = xmesa_check_for_xshm( v->display ); - } - - /* X11 graphics context */ - b->gc = XCreateGC( v->display, window, 0, NULL ); - XSetFunction( v->display, b->gc, GXcopy ); + printf("X/Mesa visual = %p\n", (void *) v); + printf("X/Mesa level = %d\n", v->mesa_visual.level); + printf("X/Mesa depth = %d\n", v->visinfo->depth); + printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); } return GL_TRUE; @@ -653,6 +599,8 @@ XMesaVisual XMesaCreateVisual( Display *display, XMesaVisual v; GLint red_bits, green_bits, blue_bits, alpha_bits; + xmesa_init( display ); + /* For debugging only */ if (_mesa_getenv("MESA_XSYNC")) { /* This makes debugging X easier. @@ -669,16 +617,16 @@ XMesaVisual XMesaCreateVisual( Display *display, v->display = display; - /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() + /* Save a copy of the XVisualInfo struct because the user may Xfree() * the struct but we may need some of the information contained in it * at a later time. */ v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); if (!v->visinfo) { - _mesa_free(v); + free(v); return NULL; } - MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); + memcpy(v->visinfo, visinfo, sizeof(*visinfo)); v->ximage_flag = ximage_flag; @@ -724,10 +672,9 @@ XMesaVisual XMesaCreateVisual( Display *display, } _mesa_initialize_visual( &v->mesa_visual, - rgb_flag, db_flag, stereo_flag, + db_flag, stereo_flag, red_bits, green_bits, blue_bits, alpha_bits, - v->mesa_visual.indexBits, depth_size, stencil_size, accum_red_size, accum_green_size, @@ -743,11 +690,25 @@ XMesaVisual XMesaCreateVisual( Display *display, PUBLIC void XMesaDestroyVisual( XMesaVisual v ) { - _mesa_free(v->visinfo); - _mesa_free(v); + free(v->visinfo); + free(v); } +/** + * Do one-time initializations. + */ +void +xmesa_init( Display *display ) +{ + static GLboolean firstTime = GL_TRUE; + if (firstTime) { + pipe_mutex_init(_xmesa_lock); + screen = driver.create_pipe_screen( display ); + firstTime = GL_FALSE; + } +} + /** * Create a new XMesaContext. @@ -759,18 +720,12 @@ void XMesaDestroyVisual( XMesaVisual v ) PUBLIC XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) { - static GLboolean firstTime = GL_TRUE; struct pipe_context *pipe = NULL; XMesaContext c; GLcontext *mesaCtx; uint pf; - if (firstTime) { - pipe_mutex_init(_xmesa_lock); - _screen = driver.create_pipe_screen(); - screen = trace_screen_create( _screen ); - firstTime = GL_FALSE; - } + xmesa_init( v->display ); /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ c = (XMesaContext) CALLOC_STRUCT(xmesa_context); @@ -811,7 +766,7 @@ fail: else if (pipe) pipe->destroy(pipe); - _mesa_free(c); + free(c); return NULL; } @@ -828,7 +783,7 @@ void XMesaDestroyContext( XMesaContext c ) screen->destroy(screen); */ - _mesa_free(c); + free(c); } @@ -1065,7 +1020,8 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, c->xm_buffer = drawBuffer; c->xm_read_buffer = readBuffer; - st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb); + st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb, + &drawBuffer->ws); xmesa_check_and_update_buffer_size(c, drawBuffer); if (readBuffer != drawBuffer) @@ -1076,7 +1032,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, } else { /* Detach */ - st_make_current( NULL, NULL, NULL ); + st_make_current( NULL, NULL, NULL, NULL ); } return GL_TRUE; @@ -1119,13 +1075,9 @@ void XMesaSwapBuffers( XMesaBuffer b ) st_swapbuffers(b->stfb, &frontLeftSurf, NULL); if (frontLeftSurf) { - if (_screen != screen) { - struct trace_surface *tr_surf = trace_surface( frontLeftSurf ); - struct pipe_surface *surf = tr_surf->surface; - frontLeftSurf = surf; - } - - driver.display_surface(b, frontLeftSurf); + screen->flush_frontbuffer( screen, + frontLeftSurf, + &b->ws ); } xmesa_check_and_update_buffer_size(NULL, b); @@ -1148,6 +1100,7 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) if (!surf_front || !surf_back) return; + assert(pipe); pipe->surface_copy(pipe, surf_front, x, y, /* dest */ surf_back, x, y, /* src */ @@ -1172,7 +1125,7 @@ XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d ) { XMesaBuffer b; for (b = XMesaBufferList; b; b = b->Next) { - if (b->drawable == d && b->xm_visual->display == dpy) { + if (b->ws.drawable == d && b->xm_visual->display == dpy) { return b; } } @@ -1206,10 +1159,10 @@ void XMesaGarbageCollect( void ) next = b->Next; if (b->xm_visual && b->xm_visual->display && - b->drawable && + b->ws.drawable && b->type == WINDOW) { XSync(b->xm_visual->display, False); - if (!window_exists( b->xm_visual->display, b->drawable )) { + if (!window_exists( b->xm_visual->display, b->ws.drawable )) { /* found a dead window, free the ancillary info */ XMesaDestroyBuffer( b ); } diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h index 63a329cbe05..de47064b410 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.h +++ b/src/gallium/state_trackers/glx/xlib/xm_api.h @@ -62,15 +62,11 @@ and create a window, you must do the following to use the X/Mesa interface: #include "state_tracker/st_public.h" #include "os/os_thread.h" +#include "state_tracker/xlib_sw_winsys.h" # include <X11/Xlib.h> # include <X11/Xlibint.h> # include <X11/Xutil.h> -# ifdef USE_XSHM /* was SHM */ -# include <sys/ipc.h> -# include <sys/shm.h> -# include <X11/extensions/XShm.h> -# endif typedef struct xmesa_buffer *XMesaBuffer; typedef struct xmesa_context *XMesaContext; @@ -316,6 +312,7 @@ typedef enum { */ struct xmesa_buffer { struct st_framebuffer *stfb; + struct xlib_drawable ws; GLboolean wasCurrent; /* was ever the current buffer? */ XMesaVisual xm_visual; /* the X/Mesa visual */ @@ -329,13 +326,6 @@ struct xmesa_buffer { XImage *tempImage; unsigned long selectedEvents;/* for pbuffers only */ - GLuint shm; /* X Shared Memory extension status: */ - /* 0 = not available */ - /* 1 = XImage support available */ - /* 2 = Pixmap support available too */ -#if defined(USE_XSHM) - XShmSegmentInfo shminfo; -#endif GC gc; /* scratch GC for span, line, tri drawing */ @@ -367,6 +357,9 @@ xmesa_buffer(GLframebuffer *fb) extern void +xmesa_init(Display *dpy); + +extern void xmesa_delete_framebuffer(struct gl_framebuffer *fb); extern XMesaBuffer @@ -394,8 +387,6 @@ xmesa_buffer_height(XMesaBuffer b) return b->stfb->Base.Height; } -extern int -xmesa_check_for_xshm(Display *display); #endif diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_public.h index 4bd5b5c8d3b..ac6a8ffb27a 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h +++ b/src/gallium/state_trackers/glx/xlib/xm_public.h @@ -29,22 +29,14 @@ #ifndef XM_WINSYS_H #define XM_WINSYS_H -struct pipe_context; -struct pipe_screen; -struct pipe_surface; -struct xmesa_buffer; - +struct xm_driver; +/* This is the driver interface required by the glx/xlib state tracker. + */ struct xm_driver { - - struct pipe_screen *(*create_pipe_screen)( void ); - - void (*display_surface)( struct xmesa_buffer *, - struct pipe_surface * ); - + struct pipe_screen *(*create_pipe_screen)( Display *display ); }; - extern void xmesa_set_driver( const struct xm_driver *driver ); diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README index 4a060730242..e24a262aba9 100644 --- a/src/gallium/state_trackers/python/README +++ b/src/gallium/state_trackers/python/README @@ -18,7 +18,7 @@ On a Windows machine ensure the swig command is in your PATH. Invoke scons on the top dir as - scons debug=yes statetrackers=python drivers=softpipe,trace winsys=none + scons debug=yes statetrackers=python drivers=softpipe winsys=none To use it set PYTHONPATH appropriately, e.g, in Linux do: diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 527e065cd91..781f54bf2b9 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -24,6 +24,7 @@ if 'python' in env['statetrackers']: 'ws2_32', ]) else: + env.Append(CPPDEFINES = ['GCC_HASCLASSVISIBILITY']) env.Append(LIBS = [ 'GL', 'X11', @@ -33,31 +34,27 @@ if 'python' in env['statetrackers']: 'gallium.i', 'st_device.c', 'st_sample.c', + 'st_hardpipe_winsys.c', + 'st_softpipe_winsys.c', ] - drivers = [ - trace - ] + env.Prepend(LIBS = [ + ws_null, + trace, + gallium, + ]) if 'llvmpipe' in env['drivers']: + env.Append(CPPDEFINES = ['HAVE_LLVMPIPE']) env.Tool('llvm') - sources += ['st_llvmpipe_winsys.c'] - drivers += [llvmpipe] - else: - sources += ['st_softpipe_winsys.c'] - drivers += [softpipe] - - pyst = env.ConvenienceLibrary( - target = 'pyst', - source = sources, - ) + env.Prepend(LIBS = [llvmpipe]) + if 'softpipe' in env['drivers']: + env.Append(CPPDEFINES = ['HAVE_SOFTPIPE']) + env.Prepend(LIBS = [softpipe]) env['no_import_lib'] = 1 env.SharedLibrary( target = '_gallium', - source = [ - 'st_hardpipe_winsys.c', - ], - LIBS = [pyst] + drivers + gallium + env['LIBS'], + source = sources, ) diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 85c9598d069..df700bc663c 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -51,7 +51,7 @@ struct st_context { void set_blend( const struct pipe_blend_state *state ) { cso_set_blend($self->cso, state); } - + void set_fragment_sampler( unsigned index, const struct pipe_sampler_state *state ) { cso_single_sampler($self->cso, index, state); cso_single_sampler_done($self->cso); @@ -239,9 +239,9 @@ struct st_context { void set_vertex_elements(unsigned num) { $self->num_vertex_elements = num; - $self->pipe->set_vertex_elements($self->pipe, - $self->num_vertex_elements, - $self->vertex_elements); + cso_set_vertex_elements($self->cso, + $self->num_vertex_elements, + $self->vertex_elements); } /* diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index d5a14fd795d..0d87c705e75 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -35,8 +35,7 @@ #include "util/u_memory.h" #include "util/u_sampler.h" #include "util/u_simple_shaders.h" -#include "trace/tr_screen.h" -#include "trace/tr_context.h" +#include "trace/tr_public.h" #include "st_device.h" #include "st_winsys.h" @@ -76,43 +75,34 @@ st_device_destroy(struct st_device *st_dev) } -static struct st_device * -st_device_create_from_st_winsys(const struct st_winsys *st_ws) +struct st_device * +st_device_create(boolean hardware) { + struct pipe_screen *screen; struct st_device *st_dev; - - if(!st_ws->screen_create) - return NULL; - + + if (hardware) + screen = st_hardware_screen_create(); + else + screen = st_software_screen_create(); + + screen = trace_screen_create(screen); + if (!screen) + goto no_screen; + st_dev = CALLOC_STRUCT(st_device); - if(!st_dev) - return NULL; + if (!st_dev) + goto no_device; pipe_reference_init(&st_dev->reference, 1); - st_dev->st_ws = st_ws; - - st_dev->real_screen = st_ws->screen_create(); - if(!st_dev->real_screen) { - st_device_destroy(st_dev); - return NULL; - } - - st_dev->screen = trace_screen_create(st_dev->real_screen); - if(!st_dev->screen) { - st_device_destroy(st_dev); - return NULL; - } + st_dev->screen = screen; return st_dev; -} - -struct st_device * -st_device_create(boolean hardware) { - if(hardware) - return st_device_create_from_st_winsys(&st_hardpipe_winsys); - else - return st_device_create_from_st_winsys(&st_softpipe_winsys); +no_device: + screen->destroy(screen); +no_screen: + return NULL; } @@ -247,7 +237,7 @@ st_context_create(struct st_device *st_dev) memset( &templat, 0, sizeof( templat ) ); templat.target = PIPE_TEXTURE_2D; - templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; templat.width0 = 1; templat.height0 = 1; templat.depth0 = 1; diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index dee9a8ca7b5..dcd0dc6e273 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -47,7 +47,8 @@ struct st_surface }; -struct st_context { +struct st_context +{ struct st_device *st_dev; struct pipe_context *pipe; @@ -72,13 +73,11 @@ struct st_context { }; -struct st_device { +struct st_device +{ /* FIXME: we also need to refcount for textures and surfaces... */ struct pipe_reference reference; - const struct st_winsys *st_ws; - - struct pipe_screen *real_screen; struct pipe_screen *screen; }; diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c index a3110a19d5d..b141177b793 100644 --- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c @@ -54,11 +54,6 @@ static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL; static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL; -/* XXX: Force init_gallium symbol to be linked */ -extern void init_gallium(void); -void (*force_init_gallium_linkage)(void) = &init_gallium; - - #ifdef PIPE_OS_WINDOWS static INLINE boolean @@ -207,16 +202,11 @@ st_hardpipe_load(void) #endif -static struct pipe_screen * -st_hardpipe_screen_create(void) +struct pipe_screen * +st_hardware_screen_create(void) { if(st_hardpipe_load()) return pfnGetGalliumScreenMESA(); else - return st_softpipe_winsys.screen_create(); + return st_software_screen_create(); } - - -const struct st_winsys st_hardpipe_winsys = { - &st_hardpipe_screen_create -}; diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c deleted file mode 100644 index 5d83b5a9e15..00000000000 --- a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************** - * - * Copyright 2010 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/** - * @file - * Llvmpipe support. - * - * @author Jose Fonseca - */ - - -#include "pipe/p_format.h" -#include "pipe/p_context.h" -#include "util/u_inlines.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "llvmpipe/lp_winsys.h" -#include "st_winsys.h" - - -static boolean -llvmpipe_ws_is_displaytarget_format_supported( struct llvmpipe_winsys *ws, - enum pipe_format format ) -{ - return FALSE; -} - - -static void * -llvmpipe_ws_displaytarget_map(struct llvmpipe_winsys *ws, - struct llvmpipe_displaytarget *dt, - unsigned flags ) -{ - assert(0); - return NULL; -} - - -static void -llvmpipe_ws_displaytarget_unmap(struct llvmpipe_winsys *ws, - struct llvmpipe_displaytarget *dt ) -{ - assert(0); -} - - -static void -llvmpipe_ws_displaytarget_destroy(struct llvmpipe_winsys *winsys, - struct llvmpipe_displaytarget *dt) -{ - assert(0); -} - - -static struct llvmpipe_displaytarget * -llvmpipe_ws_displaytarget_create(struct llvmpipe_winsys *winsys, - enum pipe_format format, - unsigned width, unsigned height, - unsigned alignment, - unsigned *stride) -{ - return NULL; -} - - -static void -llvmpipe_ws_displaytarget_display(struct llvmpipe_winsys *winsys, - struct llvmpipe_displaytarget *dt, - void *context_private) -{ - assert(0); -} - - -static void -llvmpipe_ws_destroy(struct llvmpipe_winsys *winsys) -{ - FREE(winsys); -} - - -static struct pipe_screen * -st_llvmpipe_screen_create(void) -{ - static struct llvmpipe_winsys *winsys; - struct pipe_screen *screen; - - winsys = CALLOC_STRUCT(llvmpipe_winsys); - if (!winsys) - goto no_winsys; - - winsys->destroy = llvmpipe_ws_destroy; - winsys->is_displaytarget_format_supported = llvmpipe_ws_is_displaytarget_format_supported; - winsys->displaytarget_create = llvmpipe_ws_displaytarget_create; - winsys->displaytarget_map = llvmpipe_ws_displaytarget_map; - winsys->displaytarget_unmap = llvmpipe_ws_displaytarget_unmap; - winsys->displaytarget_display = llvmpipe_ws_displaytarget_display; - winsys->displaytarget_destroy = llvmpipe_ws_displaytarget_destroy; - - screen = llvmpipe_create_screen(winsys); - if (!screen) - goto no_screen; - - return screen; - -no_screen: - FREE(winsys); -no_winsys: - return NULL; -} - - - -const struct st_winsys st_softpipe_winsys = { - &st_llvmpipe_screen_create -}; diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c index 32a6551a87a..e1808153461 100644 --- a/src/gallium/state_trackers/python/st_sample.c +++ b/src/gallium/state_trackers/python/st_sample.c @@ -485,7 +485,7 @@ st_sample_generic_pixel_block(enum pipe_format format, w, h, rgba, rgba_stride); - if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) { + if(format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) { for(y = 0; y < h; ++y) { for(x = 0; x < w; ++x) { for(ch = 0; ch < 4; ++ch) { diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index 81676bc3a4f..985374190c3 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -26,18 +26,47 @@ * **************************************************************************/ -/** - * @file - * Softpipe support. - * - * @author Keith Whitwell - * @author Brian Paul - * @author Jose Fonseca - */ - -#include "softpipe/sp_winsys.h" +#include "util/u_debug.h" +#include "softpipe/sp_public.h" +#include "llvmpipe/lp_public.h" +#include "state_tracker/sw_winsys.h" +#include "null/null_sw_winsys.h" #include "st_winsys.h" -const struct st_winsys st_softpipe_winsys = { - &softpipe_create_screen_malloc -}; + +struct pipe_screen * +st_software_screen_create(void) +{ + struct sw_winsys *ws; + const char *default_driver; + const char *driver; + struct pipe_screen *screen = NULL; + +#if defined(HAVE_LLVMPIPE) + default_driver = "llvmpipe"; +#elif defined(HAVE_SOFTPIPE) + default_driver = "softpipe"; +#else + default_driver = ""; +#endif + + ws = null_sw_create(); + if(!ws) + return NULL; + + driver = debug_get_option("GALLIUM_DRIVER", default_driver); + +#ifdef HAVE_LLVMPIPE + if (strcmp(driver, "llvmpipe") == 0) { + screen = llvmpipe_create_screen(ws); + } +#endif + +#ifdef HAVE_SOFTPIPE + if (strcmp(driver, "softpipe") == 0) { + screen = softpipe_create_screen(ws); + } +#endif + + return screen; +} diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h index 0c7b6a200e1..e1a99383a41 100644 --- a/src/gallium/state_trackers/python/st_winsys.h +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -31,19 +31,13 @@ struct pipe_screen; -struct pipe_context; -struct st_winsys -{ - struct pipe_screen * - (*screen_create)(void); -}; +struct pipe_screen * +st_hardware_screen_create(void); - -extern const struct st_winsys st_softpipe_winsys; - -extern const struct st_winsys st_hardpipe_winsys; +struct pipe_screen * +st_software_screen_create(void); #endif /* ST_WINSYS_H_ */ diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile index 037d8dc911a..7f04b2aa832 100644 --- a/src/gallium/state_trackers/vega/Makefile +++ b/src/gallium/state_trackers/vega/Makefile @@ -53,7 +53,7 @@ INCLUDE_DIRS = \ .c.o: - $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@ + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index 20c72c1ff54..02248ad4337 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -67,7 +67,7 @@ static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx, memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_1D; - templ.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; templ.last_level = 0; templ.width0 = color_data_len; templ.height0 = 1; diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c index 9c123a4cf95..7eb5ea1f078 100644 --- a/src/gallium/state_trackers/vega/api_masks.c +++ b/src/gallium/state_trackers/vega/api_masks.c @@ -86,6 +86,8 @@ draw_clear_quad(struct vg_context *st, /* draw */ if (buf) { + cso_set_vertex_elements(st->cso_context, 2, st->velems); + util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c index 2e10965be4f..41c979bfecf 100644 --- a/src/gallium/state_trackers/vega/image.c +++ b/src/gallium/state_trackers/vega/image.c @@ -48,16 +48,16 @@ static enum pipe_format vg_format_to_pipe(VGImageFormat format) { switch(format) { case VG_sRGB_565: - return PIPE_FORMAT_R5G6B5_UNORM; + return PIPE_FORMAT_B5G6R5_UNORM; case VG_sRGBA_5551: - return PIPE_FORMAT_A1R5G5B5_UNORM; + return PIPE_FORMAT_B5G5R5A1_UNORM; case VG_sRGBA_4444: - return PIPE_FORMAT_A4R4G4B4_UNORM; + return PIPE_FORMAT_B4G4R4A4_UNORM; case VG_sL_8: case VG_lL_8: return PIPE_FORMAT_L8_UNORM; case VG_BW_1: - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_B8G8R8A8_UNORM; case VG_A_8: return PIPE_FORMAT_A8_UNORM; #ifdef OPENVG_VERSION_1_1 @@ -66,7 +66,7 @@ static enum pipe_format vg_format_to_pipe(VGImageFormat format) return PIPE_FORMAT_A8_UNORM; #endif default: - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_B8G8R8A8_UNORM; } } diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c index 467b95b7519..839dc19a3b8 100644 --- a/src/gallium/state_trackers/vega/mask.c +++ b/src/gallium/state_trackers/vega/mask.c @@ -488,7 +488,7 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height) memset(&pt, 0, sizeof(pt)); pt.target = PIPE_TEXTURE_2D; - pt.format = PIPE_FORMAT_A8R8G8B8_UNORM; + pt.format = PIPE_FORMAT_B8G8R8A8_UNORM; pt.last_level = 0; pt.width0 = width; pt.height0 = height; diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c index 3405d635f0c..cdb87d3bf68 100644 --- a/src/gallium/state_trackers/vega/paint.c +++ b/src/gallium/state_trackers/vega/paint.c @@ -151,7 +151,7 @@ static INLINE struct pipe_texture *create_gradient_texture(struct vg_paint *p) memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_1D; - templ.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; templ.last_level = 0; templ.width0 = 1024; templ.height0 = 1; @@ -639,9 +639,6 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa } break; default: - samplers[0] = &paint->pattern.sampler; /* dummy */ - textures[0] = 0; - return 0; break; } return 0; diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index c06dbf52069..eef2c1eb876 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -292,12 +292,12 @@ static void draw_polygon(struct vg_context *ctx, pipe->set_vertex_buffers(pipe, 1, &vbuffer); /* tell pipe about the vertex attributes */ + memset(&velement, 0, sizeof(velement)); velement.src_offset = 0; velement.instance_divisor = 0; velement.vertex_buffer_index = 0; velement.src_format = PIPE_FORMAT_R32G32_FLOAT; - velement.nr_components = COMPONENTS; - pipe->set_vertex_elements(pipe, 1, &velement); + cso_set_vertex_elements(ctx->cso_context, 1, &velement); /* draw */ pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 05620efa9c0..47e8b470a11 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -210,6 +210,7 @@ void renderer_draw_quad(struct renderer *r, buf = setup_vertex_data(r, x1, y1, x2, y2, depth); if (buf) { + cso_set_vertex_elements(r->cso, 2, r->owner->velems); util_draw_vertex_buffer(r->pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ @@ -248,6 +249,7 @@ void renderer_draw_texture(struct renderer *r, s0, t0, s1, t1, 0.0f); if (buf) { + cso_set_vertex_elements(r->cso, 2, r->owner->velems); util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ @@ -370,6 +372,7 @@ void renderer_copy_texture(struct renderer *ctx, 0.0f); if (buf) { + cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems); util_draw_vertex_buffer(ctx->pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ @@ -535,6 +538,7 @@ void renderer_copy_surface(struct renderer *ctx, (float) dstX1, (float) dstY1, z); if (buf) { + cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems); util_draw_vertex_buffer(ctx->pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ @@ -587,6 +591,7 @@ void renderer_texture_quad(struct renderer *r, s0, t0, s1, t1, 0.0f); if (buf) { + cso_set_vertex_elements(r->cso, 2, r->owner->velems); util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index 426bf9bc62b..170391ec031 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -72,6 +72,7 @@ struct vg_context * vg_create_context(struct pipe_context *pipe, struct vg_context *share) { struct vg_context *ctx; + unsigned i; ctx = CALLOC_STRUCT(vg_context); @@ -103,6 +104,13 @@ struct vg_context * vg_create_context(struct pipe_context *pipe, ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; ctx->blend_sampler.normalized_coords = 0; + for (i = 0; i < 2; i++) { + ctx->velems[i].src_offset = i * 4 * sizeof(float); + ctx->velems[i].instance_divisor = 0; + ctx->velems[i].vertex_buffer_index = 0; + ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + } + vg_set_error(ctx, VG_NO_ERROR); ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create(); diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h index bc88c8d139d..804e9e76d77 100644 --- a/src/gallium/state_trackers/vega/vg_context.h +++ b/src/gallium/state_trackers/vega/vg_context.h @@ -146,6 +146,7 @@ struct vg_context struct vg_shader *clear_vs; struct vg_shader *texture_vs; struct pipe_buffer *vs_const_buffer; + struct pipe_vertex_element velems[2]; }; struct vg_object { diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c index a94dfb160c9..a002e50faf7 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.c +++ b/src/gallium/state_trackers/vega/vg_tracker.c @@ -51,7 +51,7 @@ create_texture(struct pipe_context *pipe, enum pipe_format format, templ.format = format; } else { - templ.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; } templ.target = PIPE_TEXTURE_2D; @@ -186,7 +186,7 @@ struct st_framebuffer * st_create_framebuffer(const void *visual, if (stencilFormat == depthFormat) stfb->dsrb = st_new_renderbuffer_fb(stencilFormat); else - stfb->dsrb = st_new_renderbuffer_fb(PIPE_FORMAT_S8Z24_UNORM); + stfb->dsrb = st_new_renderbuffer_fb(PIPE_FORMAT_Z24S8_UNORM); /*### currently we always allocate it but it's possible it's not necessary if EGL_ALPHA_MASK_SIZE was 0 @@ -209,12 +209,12 @@ static void setup_new_alpha_mask(struct vg_context *ctx, struct pipe_texture *old_texture = stfb->alpha_mask; /* - we use PIPE_FORMAT_A8R8G8B8_UNORM because we want to render to + we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to this texture and use it as a sampler, so while this wastes some space it makes both of those a lot simpler */ stfb->alpha_mask = - create_texture(pipe, PIPE_FORMAT_A8R8G8B8_UNORM, width, height); + create_texture(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height); if (!stfb->alpha_mask) { if (old_texture) @@ -327,7 +327,7 @@ void st_resize_framebuffer(struct st_framebuffer *stfb, setup_new_alpha_mask(ctx, stfb, width, height); pipe_texture_reference( &stfb->blend_texture, NULL ); - stfb->blend_texture = create_texture(ctx->pipe, PIPE_FORMAT_A8R8G8B8_UNORM, + stfb->blend_texture = create_texture(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height); } @@ -376,11 +376,19 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb) boolean st_make_current(struct vg_context *st, struct st_framebuffer *draw, - struct st_framebuffer *read) + struct st_framebuffer *read, + void *winsys_drawable_handle) { vg_set_current_context(st); if (st) { st->draw_buffer = draw; + + /* VG state tracker doesn't seem to do front-buffer rendering + * (no calls to flush_frontbuffer). If it ever did start doing + * that, it would need to pass this value down in the + * flush_frontbuffer call: + */ + st->pipe->priv = winsys_drawable_handle; } return VG_TRUE; } diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h index c1196954a76..165a6b7a332 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.h +++ b/src/gallium/state_trackers/vega/vg_tracker.h @@ -101,7 +101,8 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb); PUBLIC boolean st_make_current(struct vg_context *st, struct st_framebuffer *draw, - struct st_framebuffer *read); + struct st_framebuffer *read, + void *winsys_drawable_handle); PUBLIC struct vg_context *st_get_current(void); diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c index 05ccd5febcf..1f11b649c3e 100644 --- a/src/gallium/state_trackers/wgl/stw_context.c +++ b/src/gallium/state_trackers/wgl/stw_context.c @@ -226,7 +226,7 @@ DrvDeleteContext( /* Unbind current if deleting current context. */ if (curctx == ctx) - st_make_current( NULL, NULL, NULL ); + st_make_current( NULL, NULL, NULL, NULL ); st_destroy_context(ctx->st); FREE(ctx); @@ -317,7 +317,7 @@ stw_make_current( } if (hdc == NULL || dhglrc == 0) { - return st_make_current( NULL, NULL, NULL ); + return st_make_current( NULL, NULL, NULL, NULL ); } pipe_mutex_lock( stw_dev->ctx_mutex ); @@ -352,7 +352,7 @@ stw_make_current( /* pass to stw_flush_frontbuffer as context_private */ ctx->st->pipe->priv = hdc; - if(!st_make_current( ctx->st, fb->stfb, fb->stfb )) + if(!st_make_current( ctx->st, fb->stfb, fb->stfb, hdc )) goto fail; success: @@ -367,7 +367,7 @@ success: fail: if(fb) stw_framebuffer_release(fb); - st_make_current( NULL, NULL, NULL ); + st_make_current( NULL, NULL, NULL, NULL ); return FALSE; } diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c index e5fa6ac8eb4..ea300f27cb5 100644 --- a/src/gallium/state_trackers/wgl/stw_device.c +++ b/src/gallium/state_trackers/wgl/stw_device.c @@ -33,11 +33,6 @@ #include "pipe/p_screen.h" #include "state_tracker/st_public.h" -#ifdef DEBUG -#include "trace/tr_screen.h" -#include "trace/tr_texture.h" -#endif - #include "stw_device.h" #include "stw_winsys.h" #include "stw_pixelformat.h" @@ -47,7 +42,6 @@ #ifdef WIN32_THREADS extern _glthread_Mutex OneTimeLock; -extern void FreeAllTSD(void); #endif @@ -108,13 +102,10 @@ stw_init(const struct stw_winsys *stw_winsys) if(stw_winsys->get_adapter_luid) stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid); -#ifdef DEBUG - stw_dev->screen = trace_screen_create(screen); - stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE; -#else stw_dev->screen = screen; -#endif - + + /* XXX + */ stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer; pipe_mutex_init( stw_dev->ctx_mutex ); @@ -183,7 +174,8 @@ stw_cleanup(void) #ifdef WIN32_THREADS _glthread_DESTROY_MUTEX(OneTimeLock); - FreeAllTSD(); + + _glapi_destroy_multithread(); #endif #ifdef DEBUG diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h index a83841f6b7d..2e9ba197dfa 100644 --- a/src/gallium/state_trackers/wgl/stw_device.h +++ b/src/gallium/state_trackers/wgl/stw_device.h @@ -48,10 +48,6 @@ struct stw_device struct pipe_screen *screen; -#ifdef DEBUG - boolean trace_running; -#endif - LUID AdapterLuid; struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS]; diff --git a/src/gallium/state_trackers/wgl/stw_ext_gallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c index 8dd63f124ad..5ecbd8048de 100644 --- a/src/gallium/state_trackers/wgl/stw_ext_gallium.c +++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c @@ -31,11 +31,6 @@ #include "stw_winsys.h" #include "stw_ext_gallium.h" -#ifdef DEBUG -#include "trace/tr_screen.h" -#include "trace/tr_context.h" -#endif - struct pipe_screen * APIENTRY wglGetGalliumScreenMESA(void) diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c index 02de21ccb2b..4f1629de2f2 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c @@ -34,11 +34,6 @@ #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" -#ifdef DEBUG -#include "trace/tr_screen.h" -#include "trace/tr_texture.h" -#endif - #include "stw_icd.h" #include "stw_framebuffer.h" #include "stw_device.h" @@ -495,13 +490,6 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data) surface = (struct pipe_surface *)data->pPrivateData; -#ifdef DEBUG - if(stw_dev->trace_running) { - screen = trace_screen(screen)->screen; - surface = trace_surface(surface)->surface; - } -#endif - if(data->hSharedSurface != fb->hSharedSurface) { if(fb->shared_surface) { stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface); @@ -563,13 +551,6 @@ stw_framebuffer_present_locked(HDC hdc, else { struct pipe_screen *screen = stw_dev->screen; -#ifdef DEBUG - if(stw_dev->trace_running) { - screen = trace_screen(screen)->screen; - surface = trace_surface(surface)->surface; - } -#endif - stw_dev->stw_winsys->present( screen, surface, hdc ); stw_framebuffer_update(fb); diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index b750b03695f..bc28f31ed1c 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -74,17 +74,17 @@ struct stw_pf_depth_info static const struct stw_pf_color_info stw_pf_color[] = { /* no-alpha */ - { PIPE_FORMAT_X8R8G8B8_UNORM, { 8, 8, 8, 0}, {16, 8, 0, 0} }, - { PIPE_FORMAT_B8G8R8X8_UNORM, { 8, 8, 8, 0}, { 8, 16, 24, 0} }, - { PIPE_FORMAT_R5G6B5_UNORM, { 5, 6, 5, 0}, {11, 5, 0, 0} }, + { PIPE_FORMAT_B8G8R8X8_UNORM, { 8, 8, 8, 0}, {16, 8, 0, 0} }, + { PIPE_FORMAT_X8R8G8B8_UNORM, { 8, 8, 8, 0}, { 8, 16, 24, 0} }, + { PIPE_FORMAT_B5G6R5_UNORM, { 5, 6, 5, 0}, {11, 5, 0, 0} }, /* alpha */ - { PIPE_FORMAT_A8R8G8B8_UNORM, { 8, 8, 8, 8}, {16, 8, 0, 24} }, - { PIPE_FORMAT_B8G8R8A8_UNORM, { 8, 8, 8, 8}, { 8, 16, 24, 0} }, + { PIPE_FORMAT_B8G8R8A8_UNORM, { 8, 8, 8, 8}, {16, 8, 0, 24} }, + { PIPE_FORMAT_A8R8G8B8_UNORM, { 8, 8, 8, 8}, { 8, 16, 24, 0} }, #if 0 - { PIPE_FORMAT_A2B10G10R10_UNORM, {10, 10, 10, 2}, { 0, 10, 20, 30} }, + { PIPE_FORMAT_R10G10B10A2_UNORM, {10, 10, 10, 2}, { 0, 10, 20, 30} }, #endif - { PIPE_FORMAT_A1R5G5B5_UNORM, { 5, 5, 5, 1}, {10, 5, 0, 15} }, - { PIPE_FORMAT_A4R4G4B4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} } + { PIPE_FORMAT_B5G5R5A1_UNORM, { 5, 5, 5, 1}, {10, 5, 0, 15} }, + { PIPE_FORMAT_B4G4R4A4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} } }; @@ -92,12 +92,12 @@ static const struct stw_pf_depth_info stw_pf_depth_stencil[] = { /* pure depth */ { PIPE_FORMAT_Z32_UNORM, {32, 0} }, - { PIPE_FORMAT_Z24X8_UNORM, {24, 0} }, { PIPE_FORMAT_X8Z24_UNORM, {24, 0} }, + { PIPE_FORMAT_Z24X8_UNORM, {24, 0} }, { PIPE_FORMAT_Z16_UNORM, {16, 0} }, /* combined depth-stencil */ - { PIPE_FORMAT_S8Z24_UNORM, {24, 8} }, - { PIPE_FORMAT_Z24S8_UNORM, {24, 8} } + { PIPE_FORMAT_Z24S8_UNORM, {24, 8} }, + { PIPE_FORMAT_S8Z24_UNORM, {24, 8} } }; @@ -271,14 +271,12 @@ stw_pixelformat_visual(GLvisual *visual, memset(visual, 0, sizeof *visual); _mesa_initialize_visual( visual, - (pfi->pfd.iPixelType == PFD_TYPE_RGBA) ? GL_TRUE : GL_FALSE, (pfi->pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE, (pfi->pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE, pfi->pfd.cRedBits, pfi->pfd.cGreenBits, pfi->pfd.cBlueBits, pfi->pfd.cAlphaBits, - (pfi->pfd.iPixelType == PFD_TYPE_COLORINDEX) ? pfi->pfd.cColorBits : 0, pfi->pfd.cDepthBits, pfi->pfd.cStencilBits, pfi->pfd.cAccumRedBits, diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 221ce772af9..44f7da0f960 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -197,25 +197,26 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image) if (!crtcp->cursor_tex) { struct pipe_texture templat; - unsigned pitch; + struct winsys_handle whandle; memset(&templat, 0, sizeof(templat)); templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; - templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; + templat.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; templat.target = PIPE_TEXTURE_2D; templat.last_level = 0; templat.depth0 = 1; - templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.format = PIPE_FORMAT_B8G8R8A8_UNORM; templat.width0 = 64; templat.height0 = 64; + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_KMS; + crtcp->cursor_tex = ms->screen->texture_create(ms->screen, &templat); - ms->api->local_handle_from_texture(ms->api, - ms->screen, - crtcp->cursor_tex, - &pitch, - &crtcp->cursor_handle); + ms->screen->texture_get_handle(ms->screen, crtcp->cursor_tex, &whandle); + + crtcp->cursor_handle = whandle.handle; } transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex, diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 5b673924350..f23e4c6cc7c 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -67,7 +67,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form struct exa_pixmap_priv *exa_priv; BufferPrivatePtr private = buffer->driverPrivate; PixmapPtr pPixmap; - unsigned stride, handle; + struct winsys_handle whandle; if (pDraw->type == DRAWABLE_PIXMAP) pPixmap = (PixmapPtr) pDraw; @@ -75,6 +75,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw); exa_priv = exaGetPixmapDriverPrivate(pPixmap); + switch (buffer->attachment) { default: if (buffer->attachment != DRI2BufferFakeFrontLeft || @@ -116,19 +117,19 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form break; default: template.format = ms->ds_depth_bits_last ? - PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM; + PIPE_FORMAT_Z24X8_UNORM : PIPE_FORMAT_X8Z24_UNORM; break; } } else { template.format = ms->ds_depth_bits_last ? - PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; + PIPE_FORMAT_Z24S8_UNORM : PIPE_FORMAT_S8Z24_UNORM; } template.width0 = pDraw->width; template.height0 = pDraw->height; template.depth0 = 1; template.last_level = 0; template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + PIPE_TEXTURE_USAGE_SHARED; tex = ms->screen->texture_create(ms->screen, &template); pipe_texture_reference(&exa_priv->depth_stencil_tex, tex); } @@ -153,10 +154,13 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form if (!tex) FatalError("NO TEXTURE IN DRI2\n"); - ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle); + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_SHARED; + + ms->screen->texture_get_handle(ms->screen, tex, &whandle); - buffer->name = handle; - buffer->pitch = stride; + buffer->name = whandle.handle; + buffer->pitch = whandle.stride; buffer->cpp = 4; buffer->driverPrivate = private; buffer->flags = 0; /* not tiled */ @@ -431,11 +435,11 @@ xorg_dri2_init(ScreenPtr pScreen) dri2info.Wait = NULL; ms->d_depth_bits_last = - ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM, + ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24X8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); ms->ds_depth_bits_last = - ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_S8Z24_UNORM, + ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24S8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index f53a879a14a..004a28f00e1 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -155,7 +155,7 @@ drv_get_rec(ScrnInfoPtr pScrn) if (pScrn->driverPrivate) return TRUE; - pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); + pScrn->driverPrivate = xnfcalloc(1, sizeof(modesettingRec)); return TRUE; } @@ -183,31 +183,66 @@ drv_probe_ddc(ScrnInfoPtr pScrn, int index) static Bool drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); modesettingPtr ms = modesettingPTR(pScrn); - PixmapPtr rootPixmap; ScreenPtr pScreen = pScrn->pScreen; + int old_width, old_height; + PixmapPtr rootPixmap; + int i; if (width == pScrn->virtualX && height == pScrn->virtualY) return TRUE; + old_width = pScrn->virtualX; + old_height = pScrn->virtualY; pScrn->virtualX = width; pScrn->virtualY = height; - /* - * Remove the old framebuffer & texture. - */ - drmModeRmFB(ms->fd, ms->fb_id); - if (!ms->destroy_front_buffer(pScrn)) - FatalError("failed to destroy front buffer\n"); + /* ms->create_front_buffer will remove the old front buffer */ rootPixmap = pScreen->GetScreenPixmap(pScreen); if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL)) - return FALSE; + goto error_modify; pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8); - /* now create new frontbuffer */ - return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn); + if (!ms->create_front_buffer(pScrn) || !ms->bind_front_buffer(pScrn)) + goto error_create; + + /* + * create && bind will turn off all crtc(s) in the kernel so we need to + * re-enable all the crtcs again. For real HW we might want to do this + * before destroying the old framebuffer. + */ + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + if (!crtc->enabled) + continue; + + crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y); + } + + return TRUE; + + /* + * This is the error recovery path. + */ +error_create: + if (!pScreen->ModifyPixmapHeader(rootPixmap, old_width, old_height, -1, -1, -1, NULL)) + FatalError("failed to resize rootPixmap error path\n"); + + pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8); + +error_modify: + pScrn->virtualX = old_width; + pScrn->virtualY = old_height; + + if (ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn)) + return FALSE; + + FatalError("failed to setup old framebuffer\n"); + return FALSE; } static const xf86CrtcConfigFuncsRec crtc_config_funcs = { @@ -333,6 +368,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) EntityInfoPtr pEnt; EntPtr msEnt = NULL; int max_width, max_height; + CustomizerPtr cust; if (pScrn->numEntities != 1) return FALSE; @@ -344,6 +380,9 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) return TRUE; } + cust = (CustomizerPtr) pScrn->driverPrivate; + pScrn->driverPrivate = NULL; + /* Allocate driverPrivate */ if (!drv_get_rec(pScrn)) return FALSE; @@ -351,6 +390,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) ms = modesettingPTR(pScrn); ms->SaveGeneration = -1; ms->pEnt = pEnt; + ms->cust = cust; pScrn->displayWidth = 640; /* default it */ @@ -423,8 +463,8 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) xf86CrtcConfigInit(pScrn, &crtc_config_funcs); xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - max_width = 8192; - max_height = 8192; + max_width = 2048; /* A very low default */ + max_height = 2048; /* see screen_init */ xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { @@ -607,7 +647,9 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); + unsigned max_width, max_height; VisualPtr visual; + CustomizerPtr cust = ms->cust; if (!drv_init_drm(pScrn)) { FatalError("Could not init DRM"); @@ -624,6 +666,26 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } + /* get max width and height */ + { + drmModeResPtr res; + res = drmModeGetResources(ms->fd); + max_width = res->max_width; + max_height = res->max_height; + drmModeFreeResources(res); + } + + if (ms->screen) { + float maxf; + int max; + maxf = ms->screen->get_paramf(ms->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); + max = (1 << (int)(maxf - 1.0f)); + max_width = max < max_width ? max : max_width; + max_height = max < max_height ? max : max_height; + } + + xf86CrtcSetSizeRange(pScrn, 1, 1, max_width, max_height); + pScrn->pScreen = pScreen; /* HW dependent - FIXME */ @@ -673,7 +735,7 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86SetBlackWhitePixels(pScreen); ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE); - ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE); + ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d); if (ms->screen) { ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d); @@ -684,6 +746,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n", + ms->screen ? "Gallium3D" : "libkms"); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n", ms->screen && ms->accelerate_2d ? "enabled" : "disabled"); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n", @@ -694,6 +761,7 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n"); #endif + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n"); miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); @@ -725,8 +793,8 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - if (ms->winsys_screen_init) - ms->winsys_screen_init(pScrn); + if (cust && cust->winsys_screen_init) + cust->winsys_screen_init(cust, ms->fd); return drv_enter_vt(scrnIndex, 1); } @@ -759,10 +827,11 @@ drv_leave_vt(int scrnIndex, int flags) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + CustomizerPtr cust = ms->cust; int o; - if (ms->winsys_leave_vt) - ms->winsys_leave_vt(pScrn); + if (cust && cust->winsys_leave_vt) + cust->winsys_leave_vt(cust); for (o = 0; o < config->num_crtc; o++) { xf86CrtcPtr crtc = config->crtc[o]; @@ -778,6 +847,7 @@ drv_leave_vt(int scrnIndex, int flags) } drmModeRmFB(ms->fd, ms->fb_id); + ms->fb_id = -1; drv_restore_hw_state(pScrn); @@ -796,6 +866,7 @@ drv_enter_vt(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); + CustomizerPtr cust = ms->cust; if (drmSetMaster(ms->fd)) { if (errno == EINVAL) { @@ -826,8 +897,8 @@ drv_enter_vt(int scrnIndex, int flags) if (!xf86SetDesiredModes(pScrn)) return FALSE; - if (ms->winsys_enter_vt) - ms->winsys_enter_vt(pScrn); + if (cust && cust->winsys_enter_vt) + cust->winsys_enter_vt(cust); return TRUE; } @@ -845,13 +916,14 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; modesettingPtr ms = modesettingPTR(pScrn); + CustomizerPtr cust = ms->cust; if (pScrn->vtSema) { drv_leave_vt(scrnIndex, 0); } - if (ms->winsys_screen_close) - ms->winsys_screen_close(pScrn); + if (cust && cust->winsys_screen_close) + cust->winsys_screen_close(cust); #ifdef DRI2 if (ms->screen) @@ -900,6 +972,15 @@ static Bool drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); + + if (!ms->root_texture) + return TRUE; + + if (ms->fb_id != -1) { + drmModeRmFB(ms->fd, ms->fb_id); + ms->fb_id = -1; + } + pipe_texture_reference(&ms->root_texture, NULL); return TRUE; } @@ -908,8 +989,9 @@ static Bool drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); - unsigned handle, stride; struct pipe_texture *tex; + struct winsys_handle whandle; + unsigned fb_id; int ret; ms->noEvict = TRUE; @@ -920,10 +1002,10 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn) if (!tex) return FALSE; - if (!ms->api->local_handle_from_texture(ms->api, ms->screen, - tex, - &stride, - &handle)) + memset(&whandle, 0, sizeof(whandle)); + whandle.type = DRM_API_HANDLE_TYPE_KMS; + + if (!ms->screen->texture_get_handle(ms->screen, tex, &whandle)) goto err_destroy; ret = drmModeAddFB(ms->fd, @@ -931,21 +1013,25 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn) pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel, - stride, - handle, - &ms->fb_id); + whandle.stride, + whandle.handle, + &fb_id); if (ret) { - debug_printf("%s: failed to create framebuffer (%i, %s)", + debug_printf("%s: failed to create framebuffer (%i, %s)\n", __func__, ret, strerror(-ret)); goto err_destroy; } + if (!drv_destroy_front_buffer_ga3d(pScrn)) + FatalError("%s: failed to take down old framebuffer\n", __func__); + pScrn->frameX0 = 0; pScrn->frameY0 = 0; drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); pipe_texture_reference(&ms->root_texture, tex); pipe_texture_reference(&tex, NULL); + ms->fb_id = fb_id; return TRUE; @@ -993,6 +1079,11 @@ drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn) if (!ms->root_bo) return TRUE; + if (ms->fb_id != -1) { + drmModeRmFB(ms->fd, ms->fb_id); + ms->fb_id = -1; + } + kms_bo_unmap(ms->root_bo); kms_bo_destroy(&ms->root_bo); return TRUE; @@ -1005,6 +1096,7 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn) unsigned handle, stride; struct kms_bo *bo; unsigned attr[8]; + unsigned fb_id; int ret; attr[0] = KMS_BO_TYPE; @@ -1035,17 +1127,21 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn) pScrn->bitsPerPixel, stride, handle, - &ms->fb_id); + &fb_id); if (ret) { debug_printf("%s: failed to create framebuffer (%i, %s)", __func__, ret, strerror(-ret)); goto err_destroy; } + if (!drv_destroy_front_buffer_kms(pScrn)) + FatalError("%s: could not takedown old bo", __func__); + pScrn->frameX0 = 0; pScrn->frameY0 = 0; drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); ms->root_bo = bo; + ms->fb_id = fb_id; return TRUE; @@ -1113,4 +1209,14 @@ static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn) return TRUE; } +CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn) +{ + return modesettingPTR(pScrn)->cust; +} + +Bool xorg_has_gallium(ScrnInfoPtr pScrn) +{ + return modesettingPTR(pScrn)->screen != NULL; +} + /* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 665efdc0f03..a7ffe3f4992 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -118,22 +118,22 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_ { switch (depth) { case 32: - *format = PIPE_FORMAT_A8R8G8B8_UNORM; + *format = PIPE_FORMAT_B8G8R8A8_UNORM; *picture_format = PICT_a8r8g8b8; assert(*bbp == 32); break; case 24: - *format = PIPE_FORMAT_X8R8G8B8_UNORM; + *format = PIPE_FORMAT_B8G8R8X8_UNORM; *picture_format = PICT_x8r8g8b8; assert(*bbp == 32); break; case 16: - *format = PIPE_FORMAT_R5G6B5_UNORM; + *format = PIPE_FORMAT_B5G6R5_UNORM; *picture_format = PICT_r5g6b5; assert(*bbp == 16); break; case 15: - *format = PIPE_FORMAT_A1R5G5B5_UNORM; + *format = PIPE_FORMAT_B5G5R5A1_UNORM; *picture_format = PICT_x1r5g5b5; assert(*bbp == 16); break; @@ -144,7 +144,7 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_ break; case 4: case 1: - *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ + *format = PIPE_FORMAT_B8G8R8A8_UNORM; /* bad bad bad */ break; default: assert(0); @@ -789,7 +789,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap) return 0; } - priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY; + priv->flags |= PIPE_TEXTURE_USAGE_SCANOUT; return 0; } @@ -805,7 +805,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap) return 0; } - priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + priv->flags |= PIPE_TEXTURE_USAGE_SHARED; return 0; } @@ -943,7 +943,7 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex) { struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); - int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + int mask = PIPE_TEXTURE_USAGE_SHARED | PIPE_TEXTURE_USAGE_SCANOUT; if (!priv) return FALSE; @@ -976,8 +976,8 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn, template.depth0 = 1; template.last_level = 0; template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; - template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; - template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + template.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT; + template.tex_usage |= PIPE_TEXTURE_USAGE_SHARED; return exa->scrn->texture_create(exa->scrn, &template); } diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index 83b0d31e38d..1eb926360b9 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -68,6 +68,8 @@ renderer_draw(struct xorg_renderer *r) if (buf) { + cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems); + util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_QUADS, num_verts, /* verts */ @@ -92,6 +94,7 @@ renderer_init_state(struct xorg_renderer *r) { struct pipe_depth_stencil_alpha_state dsa; struct pipe_rasterizer_state raster; + unsigned i; /* set common initial clip state */ memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); @@ -103,6 +106,14 @@ renderer_init_state(struct xorg_renderer *r) raster.gl_rasterization_rules = 1; cso_set_rasterizer(r->cso, &raster); + /* vertex elements state */ + memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3); + for (i = 0; i < 3; i++) { + r->velems[i].src_offset = i * 4 * sizeof(float); + r->velems[i].instance_divisor = 0; + r->velems[i].vertex_buffer_index = 0; + r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + } } @@ -600,6 +611,8 @@ void renderer_draw_yuv(struct xorg_renderer *r, if (buf) { const int num_attribs = 2; /*pos + tex coord*/ + cso_set_vertex_elements(r->cso, num_attribs, r->velems); + util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_QUADS, 4, /* verts */ diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h index af6aa0567d6..3d006287199 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.h +++ b/src/gallium/state_trackers/xorg/xorg_renderer.h @@ -28,6 +28,7 @@ struct xorg_renderer { float buffer[BUF_SIZE]; int buffer_size; + struct pipe_vertex_element velems[3]; /* number of attributes per vertex for the current * draw operation */ diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index 58bb60a721d..2f5cc64d9c5 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -67,6 +67,14 @@ typedef struct #define XORG_NR_FENCES 3 +typedef struct _CustomizerRec +{ + Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd); + Bool (*winsys_screen_close)(struct _CustomizerRec *cust); + Bool (*winsys_enter_vt)(struct _CustomizerRec *cust); + Bool (*winsys_leave_vt)(struct _CustomizerRec *cust); +} CustomizerRec, *CustomizerPtr; + typedef struct _modesettingRec { /* drm */ @@ -117,12 +125,7 @@ typedef struct _modesettingRec Bool accelerate_2d; Bool debug_fallback; - /* winsys hocks */ - Bool (*winsys_screen_init)(ScrnInfoPtr pScr); - Bool (*winsys_screen_close)(ScrnInfoPtr pScr); - Bool (*winsys_enter_vt)(ScrnInfoPtr pScr); - Bool (*winsys_leave_vt)(ScrnInfoPtr pScr); - void *winsys_priv; + CustomizerPtr cust; #ifdef DRM_MODE_FEATURE_DIRTYFB DamagePtr damage; @@ -131,6 +134,9 @@ typedef struct _modesettingRec #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) +CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn); + +Bool xorg_has_gallium(ScrnInfoPtr pScrn); /*********************************************************************** * xorg_exa.c diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 0e39a390c69..12d94e0c5ca 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -101,12 +101,12 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u memset(&template, 0, sizeof(struct pipe_texture)); template.target = PIPE_TEXTURE_2D; /* XXX: Needs to match the drawable's format? */ - template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.format = PIPE_FORMAT_B8G8R8X8_UNORM; template.last_level = 0; template.width0 = width; template.height0 = height; template.depth0 = 1; - template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + template.tex_usage = PIPE_TEXTURE_USAGE_SHARED; tex = vpipe->screen->texture_create(vpipe->screen, &template); if (!tex) |