diff options
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_screen.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv30/nv30_screen.c | 19 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nv50/nv50_screen.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 9 | ||||
-rw-r--r-- | src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c | 16 |
5 files changed, 33 insertions, 25 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index a012579a9bd..3cdcc2066a4 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -147,6 +147,12 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) if (nv_dbg) nouveau_mesa_debug = atoi(nv_dbg); + /* These must be set before any failure is possible, as the cleanup + * paths assume they're responsible for deleting them. + */ + screen->drm = nouveau_drm(&dev->object); + screen->device = dev; + /* * this is initialized to 1 in nouveau_drm_screen_create after screen * is fully constructed and added to the global screen list. @@ -175,8 +181,6 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) data, size, &screen->channel); if (ret) return ret; - screen->drm = nouveau_drm(&dev->object); - screen->device = dev; ret = nouveau_client_new(screen->device, &screen->client); if (ret) diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index ea29811aa46..854f70cf34c 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -413,23 +413,20 @@ nv30_screen_destroy(struct pipe_screen *pscreen) #define FAIL_SCREEN_INIT(str, err) \ do { \ NOUVEAU_ERR(str, err); \ - nv30_screen_destroy(pscreen); \ - return NULL; \ + screen->base.base.context_create = NULL; \ + return &screen->base; \ } while(0) struct nouveau_screen * nv30_screen_create(struct nouveau_device *dev) { - struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen); + struct nv30_screen *screen; struct pipe_screen *pscreen; struct nouveau_pushbuf *push; struct nv04_fifo *fifo; unsigned oclass = 0; int ret, i; - if (!screen) - return NULL; - switch (dev->chipset & 0xf0) { case 0x30: if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f))) @@ -458,10 +455,16 @@ nv30_screen_create(struct nouveau_device *dev) if (!oclass) { NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset); - FREE(screen); return NULL; } + screen = CALLOC_STRUCT(nv30_screen); + if (!screen) + return NULL; + + pscreen = &screen->base.base; + pscreen->destroy = nv30_screen_destroy; + /* * Some modern apps try to use msaa without keeping in mind the * restrictions on videomem of older cards. Resulting in dmesg saying: @@ -479,8 +482,6 @@ nv30_screen_create(struct nouveau_device *dev) if (screen->max_sample_count > 4) screen->max_sample_count = 4; - pscreen = &screen->base.base; - pscreen->destroy = nv30_screen_destroy; pscreen->get_param = nv30_screen_get_param; pscreen->get_paramf = nv30_screen_get_paramf; pscreen->get_shader_param = nv30_screen_get_shader_param; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index e9e56e707f3..272e1d45bff 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -767,6 +767,7 @@ nv50_screen_create(struct nouveau_device *dev) if (!screen) return NULL; pscreen = &screen->base.base; + pscreen->destroy = nv50_screen_destroy; ret = nouveau_screen_init(&screen->base, dev); if (ret) { @@ -787,7 +788,6 @@ nv50_screen_create(struct nouveau_device *dev) chan = screen->base.channel; - pscreen->destroy = nv50_screen_destroy; pscreen->context_create = nv50_create; pscreen->is_format_supported = nv50_screen_is_format_supported; pscreen->get_param = nv50_screen_get_param; @@ -969,8 +969,8 @@ nv50_screen_create(struct nouveau_device *dev) return &screen->base; fail: - nv50_screen_destroy(pscreen); - return NULL; + screen->base.base.context_create = NULL; + return &screen->base; } int diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index b573ada4ba6..b5d08306596 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -618,8 +618,7 @@ nvc0_screen_resize_tls_area(struct nvc0_screen *screen, #define FAIL_SCREEN_INIT(str, err) \ do { \ NOUVEAU_ERR(str, err); \ - nvc0_screen_destroy(pscreen); \ - return NULL; \ + goto fail; \ } while(0) struct nouveau_screen * @@ -651,6 +650,7 @@ nvc0_screen_create(struct nouveau_device *dev) if (!screen) return NULL; pscreen = &screen->base.base; + pscreen->destroy = nvc0_screen_destroy; ret = nouveau_screen_init(&screen->base, dev); if (ret) { @@ -673,7 +673,6 @@ nvc0_screen_create(struct nouveau_device *dev) screen->base.vidmem_bindings = 0; } - pscreen->destroy = nvc0_screen_destroy; pscreen->context_create = nvc0_create; pscreen->is_format_supported = nvc0_screen_is_format_supported; pscreen->get_param = nvc0_screen_get_param; @@ -1066,8 +1065,8 @@ nvc0_screen_create(struct nouveau_device *dev) return &screen->base; fail: - nvc0_screen_destroy(pscreen); - return NULL; + screen->base.base.context_create = NULL; + return &screen->base; } int diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c index e117dfcd009..456530d7427 100644 --- a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c +++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c @@ -59,7 +59,7 @@ nouveau_drm_screen_create(int fd) { struct nouveau_device *dev = NULL; struct nouveau_screen *(*init)(struct nouveau_device *); - struct nouveau_screen *screen; + struct nouveau_screen *screen = NULL; int ret, dupfd = -1; pipe_mutex_lock(nouveau_screen_mutex); @@ -117,7 +117,7 @@ nouveau_drm_screen_create(int fd) } screen = init(dev); - if (!screen) + if (!screen || !screen->base.context_create) goto err; /* Use dupfd in hash table, to avoid errors if the original fd gets @@ -130,10 +130,14 @@ nouveau_drm_screen_create(int fd) return &screen->base; err: - if (dev) - nouveau_device_del(&dev); - else if (dupfd >= 0) - close(dupfd); + if (screen) { + screen->base.destroy(&screen->base); + } else { + if (dev) + nouveau_device_del(&dev); + else if (dupfd >= 0) + close(dupfd); + } pipe_mutex_unlock(nouveau_screen_mutex); return NULL; } |