aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c')
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
new file mode 100644
index 00000000000..418f1d708a7
--- /dev/null
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
@@ -0,0 +1,85 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "nouveau_drm_winsys.h"
+
+#include "nouveau_drmif.h"
+#include "nouveau_channel.h"
+#include "nouveau_bo.h"
+
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_screen.h"
+
+static void
+nouveau_drm_destroy_winsys(struct pipe_winsys *s)
+{
+ struct nouveau_winsys *nv_winsys = nouveau_winsys(s);
+ struct nouveau_screen *nv_screen= nouveau_screen(nv_winsys->pscreen);
+ nouveau_device_close(&nv_screen->device);
+ FREE(nv_winsys);
+}
+
+static struct pipe_screen *
+nouveau_drm_create_screen(struct drm_api *api, int fd)
+{
+ struct nouveau_winsys *nvws;
+ struct pipe_winsys *ws;
+ struct nouveau_device *dev = NULL;
+ struct pipe_screen *(*init)(struct pipe_winsys *,
+ struct nouveau_device *);
+ int ret;
+
+ ret = nouveau_device_open_existing(&dev, 0, fd, 0);
+ if (ret)
+ return NULL;
+
+ switch (dev->chipset & 0xf0) {
+ case 0x30:
+ case 0x40:
+ case 0x60:
+ init = nvfx_screen_create;
+ break;
+ case 0x50:
+ case 0x80:
+ case 0x90:
+ case 0xa0:
+ init = nv50_screen_create;
+ break;
+ default:
+ debug_printf("%s: unknown chipset nv%02x\n", __func__,
+ dev->chipset);
+ return NULL;
+ }
+
+ nvws = CALLOC_STRUCT(nouveau_winsys);
+ if (!nvws) {
+ nouveau_device_close(&dev);
+ return NULL;
+ }
+ ws = &nvws->base;
+ ws->destroy = nouveau_drm_destroy_winsys;
+
+ nvws->pscreen = init(ws, dev);
+ if (!nvws->pscreen) {
+ ws->destroy(ws);
+ return NULL;
+ }
+
+ return nvws->pscreen;
+}
+
+static struct drm_api nouveau_drm_api_hooks = {
+ .name = "nouveau",
+ .driver_name = "nouveau",
+ .create_screen = nouveau_drm_create_screen,
+ .destroy = NULL,
+};
+
+struct drm_api *
+drm_api_create() {
+ return &nouveau_drm_api_hooks;
+}
+