diff -up Mesa-8.0.1/src/gallium/include/state_tracker/drm_driver.h.jx Mesa-8.0.1/src/gallium/include/state_tracker/drm_driver.h --- Mesa-8.0.1/src/gallium/include/state_tracker/drm_driver.h.jx 2012-02-14 18:44:00.000000000 -0500 +++ Mesa-8.0.1/src/gallium/include/state_tracker/drm_driver.h 2012-03-23 13:11:40.785842579 -0400 @@ -43,6 +43,7 @@ struct winsys_handle enum drm_conf { /* How many frames to allow before throttling. Or -1 to indicate any number */ DRM_CONF_THROTTLE, /* DRM_CONF_INT. */ + DRM_CONF_NOTFP, DRM_CONF_MAX }; diff -up Mesa-8.0.1/src/gallium/state_trackers/dri/drm/dri2.c.jx Mesa-8.0.1/src/gallium/state_trackers/dri/drm/dri2.c --- Mesa-8.0.1/src/gallium/state_trackers/dri/drm/dri2.c.jx 2012-02-14 18:44:00.000000000 -0500 +++ Mesa-8.0.1/src/gallium/state_trackers/dri/drm/dri2.c 2012-03-23 13:11:40.785842579 -0400 @@ -642,6 +642,13 @@ static struct __DRIimageExtensionRec dri * Backend function init_screen. */ +static const __DRIextension *dri_screen_extensions_no_tfp[] = { + &dri2FlushExtension.base, + &dri2ImageExtension.base, + &dri2ConfigQueryExtension.base, + NULL +}; + static const __DRIextension *dri_screen_extensions[] = { &driTexBufferExtension.base, &dri2FlushExtension.base, @@ -671,6 +678,7 @@ dri2_init_screen(__DRIscreen * sPriv) struct dri_screen *screen; struct pipe_screen *pscreen; const struct drm_conf_ret *throttle_ret = NULL; + const struct drm_conf_ret *notfp_ret = NULL; screen = CALLOC_STRUCT(dri_screen); if (!screen) @@ -682,12 +690,16 @@ dri2_init_screen(__DRIscreen * sPriv) sPriv->driverPrivate = (void *)screen; pscreen = driver_descriptor.create_screen(screen->fd); - if (driver_descriptor.configuration) + if (driver_descriptor.configuration) { throttle_ret = driver_descriptor.configuration(DRM_CONF_THROTTLE); + throttle_ret = driver_descriptor.configuration(DRM_CONF_NOTFP); + } if (throttle_ret && throttle_ret->val.val_int != -1) { sPriv->extensions = dri_screen_extensions_throttle; screen->default_throttle_frames = throttle_ret->val.val_int; + } else if (notfp_ret && notfp_ret->val.val_bool == 1) { + sPriv->extensions = dri_screen_extensions_no_tfp; } else sPriv->extensions = dri_screen_extensions; diff -up Mesa-8.0.1/src/gallium/targets/dri-nouveau/target.c.jx Mesa-8.0.1/src/gallium/targets/dri-nouveau/target.c --- Mesa-8.0.1/src/gallium/targets/dri-nouveau/target.c.jx 2012-02-14 18:44:00.000000000 -0500 +++ Mesa-8.0.1/src/gallium/targets/dri-nouveau/target.c 2012-03-23 13:14:37.824416888 -0400 @@ -3,6 +3,12 @@ #include "state_tracker/drm_driver.h" #include "nouveau/drm/nouveau_drm_public.h" +#include +#include + +/* yes this is an ugly hack */ +static int nvfd = -1; + static struct pipe_screen * create_screen(int fd) { @@ -12,9 +18,52 @@ create_screen(int fd) if (!screen) return NULL; + nvfd = fd; + screen = debug_screen_wrap(screen); return screen; } -DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen, NULL) +static const struct drm_conf_ret notfp_ret = { + .type = DRM_CONF_BOOL, + .val.val_bool = 1, +}; + +static const struct drm_conf_ret *drm_configuration(enum drm_conf conf) +{ + switch (conf) { + case DRM_CONF_NOTFP: + { + /* have to open-code to reuse the fd */ + struct drm_nouveau_getparam g; + int vram; + + g.param = NOUVEAU_GETPARAM_CHIPSET_ID; + if (drmCommandWriteRead(nvfd, DRM_NOUVEAU_GETPARAM, &g, sizeof(g))) + return ¬fp_ret; /* error? paranoia */ + + if (g.value < 0x50) + return NULL; /* nv50+ okay */ + + if (g.value & 0xf0 == 0x30) + return ¬fp_ret; /* nv30 definitely horked */ + + g.param = NOUVEAU_GETPARAM_FB_SIZE; + if (drmCommandWriteRead(nvfd, DRM_NOUVEAU_GETPARAM, &g, sizeof(g))) + return ¬fp_ret; /* error? paranoia */ + + vram = g.value; + if ((vram >> 20) <= 64) + return ¬fp_ret; /* let's say <64M is too little */ + + return NULL; + } + + default: + break; + } + return NULL; +} + +DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen, drm_configuration) diff -up Mesa-8.0.1/src/mesa/drivers/dri/nouveau/nouveau_screen.c.jx Mesa-8.0.1/src/mesa/drivers/dri/nouveau/nouveau_screen.c --- Mesa-8.0.1/src/mesa/drivers/dri/nouveau/nouveau_screen.c.jx 2012-02-14 18:44:00.000000000 -0500 +++ Mesa-8.0.1/src/mesa/drivers/dri/nouveau/nouveau_screen.c 2012-03-23 13:38:34.477024222 -0400 @@ -37,7 +37,11 @@ #include "main/renderbuffer.h" #include "swrast/s_renderbuffer.h" +#include +#include + static const __DRIextension *nouveau_screen_extensions[]; +static const __DRIextension *nouveau_screen_extensions_notfp[]; static void nouveau_destroy_screen(__DRIscreen *dri_screen); @@ -86,6 +90,28 @@ nouveau_get_configs(void) return (const __DRIconfig **)configs; } +static int +shouldnt_tfp(int nvfd) +{ + /* have to open-code to reuse the fd */ + struct drm_nouveau_getparam g; + int vram; + + g.param = NOUVEAU_GETPARAM_CHIPSET_ID; + if (drmCommandWriteRead(nvfd, DRM_NOUVEAU_GETPARAM, &g, sizeof(g))) + return 1; /* error? paranoia */ + + g.param = NOUVEAU_GETPARAM_FB_SIZE; + if (drmCommandWriteRead(nvfd, DRM_NOUVEAU_GETPARAM, &g, sizeof(g))) + return 1; /* error? paranoia */ + + vram = g.value; + if ((vram >> 20) <= 64) + return 1; /* let's say 64M is too little */ + + return 0; +} + static const __DRIconfig ** nouveau_init_screen2(__DRIscreen *dri_screen) { @@ -99,7 +125,6 @@ nouveau_init_screen2(__DRIscreen *dri_sc return NULL; dri_screen->driverPrivate = screen; - dri_screen->extensions = nouveau_screen_extensions; screen->dri_screen = dri_screen; /* Open the DRM device. */ @@ -110,6 +135,11 @@ nouveau_init_screen2(__DRIscreen *dri_sc goto fail; } + if (shouldnt_tfp(dri_screen->fd)) + dri_screen->extensions = nouveau_screen_extensions_notfp; + else + dri_screen->extensions = nouveau_screen_extensions; + /* Choose the card specific function pointers. */ switch (screen->device->chipset & 0xf0) { case 0x00: @@ -240,6 +270,12 @@ static const __DRIextension *nouveau_scr &dri2ConfigQueryExtension.base, NULL }; + +static const __DRIextension *nouveau_screen_extensions_notfp[] = { + &nouveau_flush_extension.base, + &dri2ConfigQueryExtension.base, + NULL +}; const struct __DriverAPIRec driDriverAPI = { .InitScreen = nouveau_init_screen2,