From: Ray Strode Date: Sun, 20 Sep 2009 04:09:37 +0000 (-0400) Subject: [drm] Add initial support for nvidia cards X-Git-Tag: 0.8.0~188^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fe6ee7723abe5d0706e3f2563f99cb8b96ac5ccf;p=thirdparty%2Fplymouth.git [drm] Add initial support for nvidia cards --- diff --git a/configure.ac b/configure.ac index 5dee12a9..c98a65b9 100644 --- a/configure.ac +++ b/configure.ac @@ -56,7 +56,7 @@ PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.12.0 ]) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) -PKG_CHECK_MODULES(DRM, [libdrm libdrm_intel libdrm_radeon]) +PKG_CHECK_MODULES(DRM, [libdrm libdrm_intel libdrm_radeon libdrm_nouveau]) AC_SUBST(DRM_CFLAGS) AC_SUBST(DRM_LIBS) diff --git a/src/plugins/renderers/drm/Makefile.am b/src/plugins/renderers/drm/Makefile.am index 29bc6427..da757c59 100644 --- a/src/plugins/renderers/drm/Makefile.am +++ b/src/plugins/renderers/drm/Makefile.am @@ -20,6 +20,8 @@ drm_la_SOURCES = $(srcdir)/plugin.c \ $(srcdir)/ply-renderer-i915-driver.h \ $(srcdir)/ply-renderer-i915-driver.c \ $(srcdir)/ply-renderer-radeon-driver.h \ - $(srcdir)/ply-renderer-radeon-driver.c + $(srcdir)/ply-renderer-radeon-driver.c \ + $(srcdir)/ply-renderer-nouveau-driver.h \ + $(srcdir)/ply-renderer-nouveau-driver.c MAINTAINERCLEANFILES = Makefile.in diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c index 0be43f0b..239f8aee 100644 --- a/src/plugins/renderers/drm/plugin.c +++ b/src/plugins/renderers/drm/plugin.c @@ -59,6 +59,7 @@ #include "ply-renderer-driver.h" #include "ply-renderer-i915-driver.h" #include "ply-renderer-radeon-driver.h" +#include "ply-renderer-nouveau-driver.h" #define BYTES_PER_PIXEL (4) @@ -413,6 +414,10 @@ load_driver (ply_renderer_backend_t *backend) { backend->driver_interface = ply_renderer_radeon_driver_get_interface (); } + else if (strcmp (driver_name, "nouveau") == 0) + { + backend->driver_interface = ply_renderer_nouveau_driver_get_interface (); + } free (driver_name); if (backend->driver_interface == NULL) diff --git a/src/plugins/renderers/drm/ply-renderer-nouveau-driver.c b/src/plugins/renderers/drm/ply-renderer-nouveau-driver.c new file mode 100644 index 00000000..a94b0f4b --- /dev/null +++ b/src/plugins/renderers/drm/ply-renderer-nouveau-driver.c @@ -0,0 +1,332 @@ +/* ply-renderer-nouveau-driver.c - interface to nouveau drm driver + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Ray Strode + */ +#include "config.h" + +#include "ply-renderer-nouveau-driver.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ply-hashtable.h" +#include "ply-logger.h" +#include "ply-renderer-driver.h" + +typedef struct _ply_renderer_buffer ply_renderer_buffer_t; + +struct _ply_renderer_buffer +{ + struct nouveau_bo *object; + uint32_t id; + unsigned long width; + unsigned long height; + unsigned long row_stride; +}; + +struct _ply_renderer_driver +{ + int device_fd; + struct nouveau_device *device; + + ply_hashtable_t *buffers; +}; + +static ply_renderer_driver_t * +create_driver (int device_fd) +{ + ply_renderer_driver_t *driver; + + driver = calloc (1, sizeof (ply_renderer_driver_t)); + driver->device_fd = device_fd; + + if (nouveau_device_open_existing (&driver->device, true, + driver->device_fd, 0) < 0) + { + free (driver); + return NULL; + } + + driver->buffers = ply_hashtable_new (ply_hashtable_direct_hash, + ply_hashtable_direct_compare); + + return driver; +} + +static void +destroy_driver (ply_renderer_driver_t *driver) +{ + ply_hashtable_free (driver->buffers); + + nouveau_device_close (&driver->device); + free (driver); +} + +static ply_renderer_buffer_t * +ply_renderer_buffer_new (ply_renderer_driver_t *driver, + struct nouveau_bo *buffer_object, + uint32_t id, + unsigned long width, + unsigned long height, + unsigned long row_stride) +{ + ply_renderer_buffer_t *buffer; + + buffer = calloc (1, sizeof (ply_renderer_buffer_t)); + buffer->object = buffer_object; + buffer->id = id; + buffer->width = width; + buffer->height = height; + buffer->row_stride = row_stride; + + return buffer; +} + +static ply_renderer_buffer_t * +ply_renderer_buffer_new_from_id (ply_renderer_driver_t *driver, + uint32_t buffer_id) +{ + ply_renderer_buffer_t *buffer; + drmModeFB *fb; + struct nouveau_bo *buffer_object; + + fb = drmModeGetFB (driver->device_fd, buffer_id); + + if (fb == NULL) + return NULL; + + if (nouveau_bo_wrap (driver->device, + fb->handle, &buffer_object) < 0) + { + drmModeFreeFB (fb); + return NULL; + } + + buffer = ply_renderer_buffer_new (driver, buffer_object, buffer_id, + fb->width, fb->height, fb->pitch); + drmModeFreeFB (fb); + + return buffer; +} + +static ply_renderer_buffer_t * +get_buffer_from_id (ply_renderer_driver_t *driver, + uint32_t id) +{ + static ply_renderer_buffer_t *buffer; + + buffer = ply_hashtable_lookup (driver->buffers, (void *) (uintptr_t) id); + + return buffer; +} + +static bool +fetch_buffer (ply_renderer_driver_t *driver, + uint32_t buffer_id, + unsigned long *width, + unsigned long *height, + unsigned long *row_stride) +{ + ply_renderer_buffer_t *buffer; + + buffer = get_buffer_from_id (driver, buffer_id); + + if (buffer == NULL) + { + buffer = ply_renderer_buffer_new_from_id (driver, buffer_id); + + if (buffer == NULL) + return false; + + ply_hashtable_insert (driver->buffers, + (void *) (uintptr_t) buffer_id, + buffer); + } + + if (width != NULL) + *width = buffer->width; + + if (height != NULL) + *height = buffer->height; + + if (row_stride != NULL) + *row_stride = buffer->row_stride; + + return true; +} + + +static uint32_t +create_buffer (ply_renderer_driver_t *driver, + unsigned long width, + unsigned long height, + unsigned long *row_stride) +{ + struct nouveau_bo *buffer_object; + ply_renderer_buffer_t *buffer; + uint32_t buffer_id; + + *row_stride = ply_round_to_multiple (width * 4, 256); + + buffer_object = NULL; + if (nouveau_bo_new (driver->device, + NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 0, + height * *row_stride, &buffer_object) < 0) + { + ply_trace ("Could not allocate GEM object for frame buffer: %m"); + return 0; + } + + /* The map here forces the buffer object to be instantiated + * immediately (it's normally instantiated lazily when needed + * by other nouveau_bo api) + */ + nouveau_bo_map (buffer_object, NOUVEAU_BO_WR); + if (drmModeAddFB (driver->device_fd, width, height, + 24, 32, *row_stride, buffer_object->handle, + &buffer_id) != 0) + { + nouveau_bo_unmap (buffer_object); + ply_trace ("Could not set up GEM object as frame buffer: %m"); + nouveau_bo_ref (NULL, &buffer_object); + return 0; + } + nouveau_bo_unmap (buffer_object); + + buffer = ply_renderer_buffer_new (driver, + buffer_object, buffer_id, + width, height, *row_stride); + ply_hashtable_insert (driver->buffers, + (void *) (uintptr_t) buffer_id, + buffer); + + return buffer_id; +} + +static bool +map_buffer (ply_renderer_driver_t *driver, + uint32_t buffer_id) +{ + ply_renderer_buffer_t *buffer; + + buffer = get_buffer_from_id (driver, buffer_id); + + assert (buffer != NULL); + + return nouveau_bo_map (buffer->object, NOUVEAU_BO_WR) == 0; +} + +static void +unmap_buffer (ply_renderer_driver_t *driver, + uint32_t buffer_id) +{ + ply_renderer_buffer_t *buffer; + + buffer = get_buffer_from_id (driver, buffer_id); + + assert (buffer != NULL); + + nouveau_bo_unmap (buffer->object); +} + +static char * +begin_flush (ply_renderer_driver_t *driver, + uint32_t buffer_id) +{ + ply_renderer_buffer_t *buffer; + + buffer = get_buffer_from_id (driver, buffer_id); + + assert (buffer != NULL); + + return buffer->object->map; +} + +static void +end_flush (ply_renderer_driver_t *driver, + uint32_t buffer_id) +{ + ply_renderer_buffer_t *buffer; + + buffer = get_buffer_from_id (driver, buffer_id); + + assert (buffer != NULL); +} + +static void +destroy_buffer (ply_renderer_driver_t *driver, + uint32_t buffer_id) +{ + ply_renderer_buffer_t *buffer; + + buffer = get_buffer_from_id (driver, buffer_id); + + assert (buffer != NULL); + + drmModeRmFB (driver->device_fd, buffer->id); + + nouveau_bo_ref (NULL, &buffer->object); + + ply_hashtable_remove (driver->buffers, + (void *) (uintptr_t) buffer_id); + free (buffer); +} + +ply_renderer_driver_interface_t * +ply_renderer_nouveau_driver_get_interface (void) +{ + static ply_renderer_driver_interface_t driver_interface = + { + .create_driver = create_driver, + .destroy_driver = destroy_driver, + .create_buffer = create_buffer, + .fetch_buffer = fetch_buffer, + .map_buffer = map_buffer, + .unmap_buffer = unmap_buffer, + .begin_flush = begin_flush, + .end_flush = end_flush, + .destroy_buffer = destroy_buffer, + }; + + return &driver_interface; +} + +/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ diff --git a/src/plugins/renderers/drm/ply-renderer-nouveau-driver.h b/src/plugins/renderers/drm/ply-renderer-nouveau-driver.h new file mode 100644 index 00000000..1baed4a8 --- /dev/null +++ b/src/plugins/renderers/drm/ply-renderer-nouveau-driver.h @@ -0,0 +1,32 @@ +/* ply-renderer-nouveau-driver.h + * + * Copyright (C) 2009 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written By: Ray Strode + */ +#ifndef PLY_RENDERER_NOUVEAU_DRIVER_H +#define PLY_RENDERER_NOUVEAU_DRIVER_H + +#include "ply-renderer-driver.h" + +#ifndef PLY_HIDE_FUNCTION_DECLARATIONS +ply_renderer_driver_interface_t *ply_renderer_nouveau_driver_get_interface (void); +#endif + +#endif /* PLY_RENDERER_NOUVEAU_DRIVER_H */ +/* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */