nouveau: use dri state tracker for dri1
authorBen Skeggs <bskeggs@redhat.com>
Thu, 7 May 2009 23:04:10 +0000 (09:04 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 7 May 2009 23:32:56 +0000 (09:32 +1000)
src/gallium/winsys/drm/nouveau/Makefile
src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h [deleted file]
src/gallium/winsys/drm/nouveau/dri2/Makefile
src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h [new file with mode: 0644]
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h

index f8c81358544bd312bc65233814d6c45fa02087f5..be4cad6f9ed05f3082f7bcb669becd86cffce8d7 100644 (file)
@@ -2,7 +2,7 @@
 TOP = ../../../../..
 include $(TOP)/configs/current
 
-SUBDIRS = drm dri dri2
+SUBDIRS = drm dri2
 
 default install clean:
        @for dir in $(SUBDIRS) ; do \
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h
deleted file mode 100644 (file)
index 1207c2d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _NOUVEAU_DRI_
-#define _NOUVEAU_DRI_
-
-#include "xf86drm.h"
-#include "drm.h"
-#include "nouveau_drm.h"
-
-struct nouveau_dri {
-       uint32_t device_id;     /**< \brief PCI device ID */
-       uint32_t width;         /**< \brief width in pixels of display */
-       uint32_t height;        /**< \brief height in scanlines of display */
-       uint32_t depth;         /**< \brief depth of display (8, 15, 16, 24) */
-       uint32_t bpp;           /**< \brief bit depth of display (8, 16, 24, 32) */
-
-       uint32_t bus_type;      /**< \brief ths bus type */
-       uint32_t bus_mode;      /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */
-
-       uint32_t front_offset;  /**< \brief front buffer offset */
-       uint32_t front_pitch;   /**< \brief front buffer pitch */
-       uint32_t back_offset;   /**< \brief private back buffer offset */
-       uint32_t back_pitch;    /**< \brief private back buffer pitch */
-       uint32_t depth_offset;  /**< \brief private depth buffer offset */
-       uint32_t depth_pitch;   /**< \brief private depth buffer pitch */
-
-};
-
-#endif
-
index 377a80d5188c3bbd68067cbdc3d32d2234a5b823..024ab150cbd1878150bad1ff1ee87d9ba12394db 100644 (file)
@@ -1,7 +1,7 @@
 TOP = ../../../../../..
 include $(TOP)/configs/current
 
-LIBNAME = nouveau_dri2.so
+LIBNAME = nouveau_dri.so
 
 PIPE_DRIVERS = \
        $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h
new file mode 100644 (file)
index 0000000..1207c2d
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _NOUVEAU_DRI_
+#define _NOUVEAU_DRI_
+
+#include "xf86drm.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+
+struct nouveau_dri {
+       uint32_t device_id;     /**< \brief PCI device ID */
+       uint32_t width;         /**< \brief width in pixels of display */
+       uint32_t height;        /**< \brief height in scanlines of display */
+       uint32_t depth;         /**< \brief depth of display (8, 15, 16, 24) */
+       uint32_t bpp;           /**< \brief bit depth of display (8, 16, 24, 32) */
+
+       uint32_t bus_type;      /**< \brief ths bus type */
+       uint32_t bus_mode;      /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */
+
+       uint32_t front_offset;  /**< \brief front buffer offset */
+       uint32_t front_pitch;   /**< \brief front buffer pitch */
+       uint32_t back_offset;   /**< \brief private back buffer offset */
+       uint32_t back_pitch;    /**< \brief private back buffer pitch */
+       uint32_t depth_offset;  /**< \brief private depth buffer offset */
+       uint32_t depth_pitch;   /**< \brief private depth buffer pitch */
+
+};
+
+#endif
+
index a558fda1401fa2b70400ed4b08917ff80b1e6296..b355a1391d3472aa06d9eba967cdb47a6463393d 100644 (file)
@@ -7,9 +7,68 @@
 #include "nouveau_channel.h"
 #include "nouveau_bo.h"
 
+static struct pipe_surface *
+dri_surface_from_handle(struct pipe_screen *screen,
+                        unsigned handle,
+                        enum pipe_format format,
+                        unsigned width,
+                        unsigned height,
+                        unsigned pitch)
+{
+   struct pipe_surface *surface = NULL;
+   struct pipe_texture *texture = NULL;
+   struct pipe_texture templat;
+   struct pipe_buffer *buf = NULL;
+
+   buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle);
+   if (!buf)
+      return NULL;
+
+   memset(&templat, 0, sizeof(templat));
+   templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
+                       NOUVEAU_TEXTURE_USAGE_LINEAR;
+   templat.target = PIPE_TEXTURE_2D;
+   templat.last_level = 0;
+   templat.depth[0] = 1;
+   templat.format = format;
+   templat.width[0] = width;
+   templat.height[0] = height;
+   pf_get_block(templat.format, &templat.block);
+
+   texture = screen->texture_blanket(screen,
+                                     &templat,
+                                     &pitch,
+                                     buf);
+
+   /* we don't need the buffer from this point on */
+   pipe_buffer_reference(&buf, NULL);
+
+   if (!texture)
+      return NULL;
+
+   surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
+                                     PIPE_BUFFER_USAGE_GPU_READ |
+                                     PIPE_BUFFER_USAGE_GPU_WRITE);
+
+   /* we don't need the texture from this point on */
+   pipe_texture_reference(&texture, NULL);
+   return surface;
+}
+
+static struct pipe_surface *
+nouveau_dri1_front_surface(struct pipe_context *pipe)
+{
+       return nouveau_screen(pipe->screen)->front;
+}
+
+static struct dri1_api nouveau_dri1_api = {
+       nouveau_dri1_front_surface,
+};
+
 static struct pipe_screen *
 nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg)
 {
+       struct dri1_create_screen_arg *dri1 = (void *)arg;
        struct pipe_winsys *ws;
        struct nouveau_winsys *nvws;
        struct nouveau_device *dev = NULL;
@@ -67,6 +126,33 @@ nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg)
                return NULL;
        }
 
+       if (arg->mode == DRM_CREATE_DRI1) {
+               struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
+               struct nouveau_dri *nvdri = dri1->ddx_info;
+               enum pipe_format format;
+
+               if (nvdri->bpp == 16)
+                       format = PIPE_FORMAT_R5G6B5_UNORM;
+               else
+                       format = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+               nvpws->front = dri_surface_from_handle(nvpws->pscreen,
+                                                      nvdri->front_offset,
+                                                      format,
+                                                      nvdri->width,
+                                                      nvdri->height,
+                                                      nvdri->front_pitch *
+                                                      (nvdri->bpp / 8));
+               if (!nvpws->front) {
+                       debug_printf("%s: error referencing front buffer\n",
+                                    __func__);
+                       ws->destroy(ws);
+                       return NULL;
+               }
+
+               dri1->api = &nouveau_dri1_api;
+       }
+
        return nouveau_pipe_winsys(ws)->pscreen;
 }
 
index 2782c83c0e7390b5b98efd1f02a764bfc9008cb0..cc237bfc13ac0a1848d31718b08cd1289ceb406f 100644 (file)
@@ -1,5 +1,7 @@
 #ifndef __NOUVEAU_DRM_API_H__
 #define __NOUVEAU_DRM_API_H__
 #include "state_tracker/drm_api.h"
+#include "state_tracker/dri1_api.h"
+#include "nouveau_dri.h"
 
 #endif
index 10e1e269e8ca88d430bd3d4867149f0d4e797436..ec10f1e00c8053248741d1dd3a4c1f6d0d131802 100644 (file)
@@ -29,6 +29,8 @@ struct nouveau_pipe_winsys {
 
        unsigned nr_pctx;
        struct pipe_context **pctx;
+
+       struct pipe_surface *front;
 };
 
 static INLINE struct nouveau_pipe_winsys *