[Mesa-dev] [PATCH 2/2] gallium: add texture update hook to screen

Dave Airlie airlied at gmail.com
Mon Mar 18 21:40:37 PDT 2013


From: Dave Airlie <airlied at redhat.com>

We have cases on virtual GPU hw that renders using a wrapped llvmpipe,
that we can't produce the normal DRI2 semantics having the kernel/hw
enforce synchronisation semantics. It is also suboptimal to flush
all surfaces on the server side in the block handler. So there is
already a dri/st hook to update the texture, so create a screen interface
and call into it for the texture resource. The sw driver can then
call into the displaytarget wrapper which will call into the outer
wrapper driver to actually cause the flush to happen.

This contains the llvmpipe and wrapper sw changes.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/drivers/llvmpipe/lp_texture.c         | 13 +++++++++++++
 src/gallium/drivers/softpipe/sp_texture.h         |  2 +-
 src/gallium/include/pipe/p_screen.h               |  3 +++
 src/gallium/include/state_tracker/sw_winsys.h     |  6 ++++++
 src/gallium/state_trackers/dri/drm/dri2.c         |  5 ++++-
 src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c | 11 +++++++++++
 6 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index f923292..48242d5 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -1375,6 +1375,18 @@ llvmpipe_print_resources(void)
 }
 #endif
 
+static void
+llvmpipe_texture_update(struct pipe_screen *pscreen,
+                        struct pipe_resource *pt)
+{
+   struct llvmpipe_screen *screen = llvmpipe_screen(pscreen);
+   struct llvmpipe_resource *lpr = llvmpipe_resource(pt);
+   struct sw_winsys *winsys = screen->winsys;
+   if (!lpr->dt)
+      return;
+
+   winsys->displaytarget_update(winsys, lpr->dt);
+}
 
 void
 llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
@@ -1396,6 +1408,7 @@ llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
    screen->resource_from_handle = llvmpipe_resource_from_handle;
    screen->resource_get_handle = llvmpipe_resource_get_handle;
    screen->can_create_resource = llvmpipe_can_create_resource;
+   screen->texture_update = llvmpipe_texture_update;
 }
 
 
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 533d625..04c6eaf 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -46,7 +46,7 @@ struct softpipe_resource
    struct pipe_resource base;
 
    unsigned long level_offset[SP_MAX_TEXTURE_2D_LEVELS];
-   unsigned stride[SP_MAX_TEXTURE_2D_LEVELS];
+   int stride[SP_MAX_TEXTURE_2D_LEVELS];
 
    /**
     * Display target, only valid for PIPE_TEXTURE_2D with the
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 754cfd7..680274c 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -206,6 +206,9 @@ struct pipe_screen {
                             struct pipe_fence_handle *fence,
                             uint64_t timeout );
 
+
+   void (*texture_update)(struct pipe_screen *,
+                          struct pipe_resource *res);
 };
 
 
diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
index 71d2943..880a6d5 100644
--- a/src/gallium/include/state_tracker/sw_winsys.h
+++ b/src/gallium/include/state_tracker/sw_winsys.h
@@ -130,6 +130,12 @@ struct sw_winsys
    (*displaytarget_display)( struct sw_winsys *ws, 
                              struct sw_displaytarget *dt,
                              void *context_private );
+   
+   /* some virtual GPUs have got hw to do sync with so add an
+      interface to allow it to happen */
+   void 
+   (*displaytarget_update)( struct sw_winsys *ws, 
+                            struct sw_displaytarget *dt );
 
    void 
    (*displaytarget_destroy)( struct sw_winsys *ws, 
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index f8d311c..bfcfe3f 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -433,7 +433,10 @@ dri2_update_tex_buffer(struct dri_drawable *drawable,
                        struct dri_context *ctx,
                        struct pipe_resource *res)
 {
-   /* no-op */
+   struct pipe_context *pipe = ctx->st->pipe;
+
+   if (pipe->screen->texture_update)
+      pipe->screen->texture_update(pipe->screen, res);
 }
 
 static __DRIimage *
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
index 3761ae0..71d64c5 100644
--- a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
@@ -246,6 +246,16 @@ wsw_dt_unmap(struct sw_winsys *ws,
    wdt->transfer = NULL;
 }
 
+static void 
+wsw_dt_update( struct sw_winsys *ws, 
+               struct sw_displaytarget *dt )
+{
+   struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+   struct pipe_context *pipe = wdt->winsys->pipe;
+
+   pipe->screen->texture_update(pipe->screen, wdt->tex);
+}
+
 static void
 wsw_dt_destroy(struct sw_winsys *ws,
                struct sw_displaytarget *dt)
@@ -282,6 +292,7 @@ wrapper_sw_winsys_wrap_pipe_screen(struct pipe_screen *screen)
    wsw->base.displaytarget_map = wsw_dt_map;
    wsw->base.displaytarget_unmap = wsw_dt_unmap;
    wsw->base.displaytarget_destroy = wsw_dt_destroy;
+   wsw->base.displaytarget_update = wsw_dt_update;
    wsw->base.destroy = wsw_destroy;
 
    wsw->screen = screen;
-- 
1.8.1.4



More information about the mesa-dev mailing list