Hi Thomas,

I'd like to make these changes to make it possible to use the DRM
state tracker interface with contexts other than pipe_context. Nouveau
is the only public driver that does DRI1 from what I can see, but I've
been told that there are some closed drivers that also depend on these
interfaces and that you look after them.

Added drm_api::create_video_context() to get a pipe_video_context, you
can ignore it. Changes to the st_* lock functions are trivial and
obvious, Nouveau doesn't use them but presumably anyone who does can
return pipe_context->priv just as easily. Changes to
dri1_api::front_srf_locked() are too, hopefully your front buffer can
be accessed via pipe_screen as well. I didn't change
dri1_api::present_locked() because we don't do page flipping yet, but
I think that could be done with just a screen as well in Nouveau.
Thoughts?

---

diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h
b/src/gallium/drivers/nouveau/nouveau_winsys.h
index 42c77e5..600a86c 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -53,6 +53,12 @@ nv40_screen_create(struct pipe_winsys *ws, struct
nouveau_device *);
 extern struct pipe_context *
 nv40_create(struct pipe_screen *, unsigned pctx_id);

+extern struct pipe_video_context *
+nv40_video_create(struct pipe_context *pipe, enum pipe_video_profile profile,
+                  enum pipe_video_chroma_format chroma_format,
+                  unsigned width, unsigned height,
+                  unsigned pvctx_id);
+
 extern struct pipe_screen *
 nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *);

diff --git a/src/gallium/include/state_tracker/dri1_api.h
b/src/gallium/include/state_tracker/dri1_api.h
index b173ba3..603f5d8 100644
--- a/src/gallium/include/state_tracker/dri1_api.h
+++ b/src/gallium/include/state_tracker/dri1_api.h
@@ -29,11 +29,11 @@ struct dri1_api_version

 struct dri1_api_lock_funcs
 {
-   void (*lock) (struct pipe_context * pipe);
-   void (*unlock) (struct pipe_context * locked_pipe);
-      boolean(*is_locked) (struct pipe_context * locked_pipe);
-      boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
-   void (*clear_lost_lock) (struct pipe_context * locked_pipe);
+   void (*lock) (void *pipe_priv);
+   void (*unlock) (void *locked_pipe_priv);
+      boolean(*is_locked) (void *locked_pipe_priv);
+      boolean(*is_lock_lost) (void *locked_pipe_priv);
+   void (*clear_lost_lock) (void *locked_pipe_priv);
 };

 struct dri1_api
@@ -46,7 +46,7 @@ struct dri1_api

    /*...@{ */

-   struct pipe_surface *(*front_srf_locked) (struct pipe_context *
+   struct pipe_surface *(*front_srf_locked) (struct pipe_screen *
                                             locked_pipe);

    void (*present_locked) (struct pipe_context * locked_pipe,
diff --git a/src/gallium/include/state_tracker/drm_api.h
b/src/gallium/include/state_tracker/drm_api.h
index 4d1259e..ea0b91c 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -8,6 +8,7 @@ struct pipe_screen;
 struct pipe_winsys;
 struct pipe_buffer;
 struct pipe_context;
+struct pipe_video_context;
 struct pipe_texture;

 enum drm_create_screen_mode {
@@ -36,6 +37,11 @@ struct drm_api
                                              struct drm_create_screen_arg 
*arg);
        struct pipe_context* (*create_context)(struct drm_api *api,
                                               struct pipe_screen *screen);
+        struct pipe_video_context* (*create_video_context)(struct drm_api *api,
+                                                           struct
pipe_screen *screen,
+                                                           enum
pipe_video_profile profile,
+                                                           enum
pipe_video_chroma_format chroma_format,
+                                                           unsigned
width, unsigned height);
        /*...@}*/

        /**
diff --git a/src/gallium/state_trackers/dri/dri_context.c
b/src/gallium/state_trackers/dri/dri_context.c
index 8819936..3ddff30 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -175,33 +175,33 @@ dri_make_current(__DRIcontextPrivate * cPriv,
 }

 static void
-st_dri_lock(struct pipe_context *pipe)
+st_dri_lock(void *pipe_priv)
 {
-   dri_lock((struct dri_context *)pipe->priv);
+   dri_lock((struct dri_context *)pipe_priv);
 }

 static void
-st_dri_unlock(struct pipe_context *pipe)
+st_dri_unlock(void *pipe_priv)
 {
-   dri_unlock((struct dri_context *)pipe->priv);
+   dri_unlock((struct dri_context *)pipe_priv);
 }

 static boolean
-st_dri_is_locked(struct pipe_context *pipe)
+st_dri_is_locked(void *pipe_priv)
 {
-   return ((struct dri_context *)pipe->priv)->isLocked;
+   return ((struct dri_context *)pipe_priv)->isLocked;
 }

 static boolean
-st_dri_lost_lock(struct pipe_context *pipe)
+st_dri_lost_lock(void *pipe_priv)
 {
-   return ((struct dri_context *)pipe->priv)->wsLostLock;
+   return ((struct dri_context *)pipe_priv)->wsLostLock;
 }

 static void
-st_dri_clear_lost_lock(struct pipe_context *pipe)
+st_dri_clear_lost_lock(void *pipe_priv)
 {
-   ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
+   ((struct dri_context *)pipe_priv)->wsLostLock = FALSE;
 }

 struct dri1_api_lock_funcs dri1_lf = {
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index f512c0e..97e7426 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -46,9 +46,9 @@ dri_surface_from_handle(struct drm_api *api, struct
pipe_screen *pscreen,
 }

 static struct pipe_surface *
-nouveau_dri1_front_surface(struct pipe_context *pipe)
+nouveau_dri1_front_surface(struct pipe_screen *screen)
 {
-       return nouveau_winsys_screen(pipe->screen)->front;
+       return nouveau_winsys_screen(screen)->front;
 }

 static struct dri1_api nouveau_dri1_api = {
@@ -191,6 +191,54 @@ nouveau_drm_create_context(struct drm_api *api,
struct pipe_screen *pscreen)
        return nvws->pctx[i];
 }

+typedef struct pipe_video_context* (*nouveau_video_create)(struct
pipe_context *pipe,
+                                                           enum
pipe_video_profile profile,
+                                                           enum
pipe_video_chroma_format chroma_format,
+                                                           unsigned
width, unsigned height,
+                                                           unsigned pvctx);
+
+static struct pipe_video_context *
+nouveau_drm_create_video_context(struct drm_api *api, struct
pipe_screen *pscreen,
+                                 enum pipe_video_profile profile,
+                                 enum pipe_video_chroma_format chroma_format,
+                                 unsigned width, unsigned height)
+{
+       struct nouveau_winsys *nvws = nouveau_winsys_screen(pscreen);
+        nouveau_video_create init;
+       unsigned chipset = nouveau_screen(pscreen)->device->chipset;
+        struct pipe_context *pipe;
+       int i;
+
+       switch (chipset & 0xf0) {
+       case 0x40:
+       case 0x60:
+               init = nv40_video_create;
+               break;
+       default:
+               debug_printf("%s: unknown chipset nv%02x\n", __func__, chipset);
+               return NULL;
+       }
+
+       /* Find a free slot for a pipe video context, allocate a new one if 
needed */
+       for (i = 0; i < nvws->nr_pvctx; i++) {
+               if (nvws->pvctx[i] == NULL)
+                       break;
+       }
+
+       if (i == nvws->nr_pvctx) {
+               nvws->nr_pvctx++;
+               nvws->pvctx = realloc(nvws->pvctx,
+                                     sizeof(*nvws->pvctx) * nvws->nr_pvctx);
+       }
+
+        pipe = nouveau_drm_create_context(api, pscreen);
+        if (!pipe)
+           return NULL;
+
+       nvws->pvctx[i] = init(pipe, profile, chroma_format, width, height, i);
+       return nvws->pvctx[i];
+}
+
 static struct pipe_texture *
 nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen,
                         struct pipe_texture *templ, const char *name,
@@ -255,6 +303,7 @@ nouveau_drm_handle_from_pt(struct drm_api *api,
struct pipe_screen *pscreen,
 struct drm_api drm_api_hooks = {
        .create_screen = nouveau_drm_create_screen,
        .create_context = nouveau_drm_create_context,
+        .create_video_context = nouveau_drm_create_video_context,
        .texture_from_shared_handle = nouveau_drm_pt_from_name,
        .shared_handle_from_texture = nouveau_drm_name_from_pt,
        .local_handle_from_texture = nouveau_drm_handle_from_pt,
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
index e61e0e0..fa4e821 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
@@ -15,6 +15,8 @@ struct nouveau_winsys {

        unsigned nr_pctx;
        struct pipe_context **pctx;
+        unsigned nr_pvctx;
+        struct pipe_video_context **pvctx;

        struct pipe_surface *front;
 };

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to