st/dri/sw: add drisw_api similarly to dri1_api
authorGeorge Sapountzis <gsapountzis@gmail.com>
Mon, 29 Mar 2010 18:06:54 +0000 (21:06 +0300)
committerGeorge Sapountzis <gsapountzis@gmail.com>
Mon, 29 Mar 2010 18:06:54 +0000 (21:06 +0300)
I am pretty sure that this is in gallium spirit, so commit. Thanks to Chia-I
for suggesting this.

src/gallium/include/state_tracker/dri1_api.h
src/gallium/include/state_tracker/drisw_api.h [new file with mode: 0644]
src/gallium/state_trackers/dri/common/dri_st_api.c
src/gallium/state_trackers/dri/drm/dri1.c
src/gallium/state_trackers/dri/sw/drisw.c
src/gallium/state_trackers/dri/sw/drisw.h
src/gallium/targets/dri-swrast/swrast_drm_api.c
src/gallium/targets/libgl-xlib/xlib.c
src/gallium/winsys/sw/dri/dri_sw_winsys.c
src/gallium/winsys/sw/dri/dri_sw_winsys.h

index 27b7a28c46749830406cfa61c397ef4fb5ffcac2..bb1cd6d1d821ff4422f6788b76f6657b882d2dda 100644 (file)
@@ -7,14 +7,14 @@
 
 #include "state_tracker/drm_api.h"
 
-struct drm_clip_rect;
-
 struct pipe_screen;
 struct pipe_winsys;
 struct pipe_buffer;
 struct pipe_context;
 struct pipe_texture;
 
+struct drm_clip_rect;
+
 struct dri1_api_version
 {
    int major;
@@ -31,8 +31,8 @@ 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);
+   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);
 };
 
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
new file mode 100644 (file)
index 0000000..c6adebb
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _DRISW_API_H_
+#define _DRISW_API_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_format.h"
+
+#include "state_tracker/drm_api.h"
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_buffer;
+struct pipe_context;
+struct pipe_texture;
+
+struct dri_drawable;
+
+/**
+ * This callback struct is intended for the winsys to call the loader.
+ */
+
+struct drisw_loader_funcs
+{
+   void (*put_image) (struct dri_drawable *dri_drawable,
+                      void *data, unsigned width, unsigned height);
+};
+
+struct drisw_create_screen_arg
+{
+   struct drm_create_screen_arg base;
+
+   struct drisw_loader_funcs *lf;
+};
+
+#endif
index 40b24b18e9f40e8a5715b6a2c1043383f88a32e6..7ba7ec383d8e86979f9b702c491171727a51148a 100644 (file)
@@ -80,7 +80,7 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
       }
 #else
       if (new_stamp)
-         drisw_update_drawable_info(drawable->dPriv);
+         drisw_update_drawable_info(drawable);
 
       drisw_allocate_textures(drawable, statt_mask);
 #endif
index aad098bb301587a45f74c48c3f8e376270a6f266..9b5842ba2bf3d2e28d9fcc42e4c2eb39355a2c9f 100644 (file)
@@ -404,6 +404,19 @@ dri1_allocate_textures(struct dri_drawable *drawable,
    drawable->old_h = height;
 }
 
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *dri1_screen_extensions[] = {
+   &driReadDrawableExtension,
+   &driCopySubBufferExtension.base,
+   &driSwapControlExtension.base,
+   &driFrameTrackingExtension.base,
+   &driMediaStreamCounterExtension.base,
+   NULL
+};
+
 static void
 st_dri_lock(struct pipe_context *pipe)
 {
@@ -442,21 +455,6 @@ static struct dri1_api_lock_funcs dri1_lf = {
    .clear_lost_lock = st_dri_clear_lost_lock
 };
 
-/*
- * Backend function for init_screen.
- */
-
-static const __DRIextension *dri1_screen_extensions[] = {
-   &driReadDrawableExtension,
-   &driCopySubBufferExtension.base,
-   &driSwapControlExtension.base,
-   &driFrameTrackingExtension.base,
-   &driMediaStreamCounterExtension.base,
-   NULL
-};
-
-struct dri1_api *__dri1_api_hooks = NULL;
-
 static INLINE void
 dri1_copy_version(struct dri1_api_version *dst,
                  const struct __DRIversionRec *src)
@@ -466,6 +464,8 @@ dri1_copy_version(struct dri1_api_version *dst,
    dst->patch_level = src->patch;
 }
 
+struct dri1_api *__dri1_api_hooks = NULL;
+
 const __DRIconfig **
 dri1_init_screen(__DRIscreen * sPriv)
 {
index b7eba63bcb9a3f86e3f7b4aa62ec9f740710c134..b82567109722549a9b7f16d612c55d52556547d0 100644 (file)
  **************************************************************************/
 
 /* TODO:
- *
- * stride:
- *
- * The driver and the loaders (libGL, xserver/glx) compute the stride from the
- * width independently. winsys has a workaround that works for softpipe but may
- * explode for other drivers or platforms, rendering- or performance-wise.
- * Solving this issue properly requires extending the DRISW loader extension,
- * in order to make the stride available to the putImage callback.
- *
- * drisw_api:
- *
- * Define drisw_api similarly to dri1_api and use it to call the loader. This
- * is predicated on support for calling the loader from the winsys, which has
- * to grow for DRI2 as well.
  *
  * xshm / texture_from_pixmap / EGLImage:
  *
  * Allow the loaders to use the XSHM extension. It probably requires callbacks
- * for createImage/destroyImage similar to DRI2 getBuffers. Probably not worth
- * it, given the scope of DRISW, unless it falls naturally from properly
- * solving the other issues.
- *
- * fences:
- *
- * No fences are used, are they needed for llvmpipe / cell ?
+ * for createImage/destroyImage similar to DRI2 getBuffers.
  */
 
 #include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
 #include "pipe/p_context.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drisw_api.h"
 
 #include "dri_screen.h"
 #include "dri_context.h"
@@ -80,60 +60,47 @@ get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
                            dPriv->loaderPrivate);
 }
 
-/*
- * Set the width to 'stride / cpp'. PutImage seems to correctly clip the width
- * to the actual width of the dst drawable. Even if this is not specified but
- * an implementation detail, it is the correct thing to do, so rely on it. XXX
- */
 static INLINE void
-put_image(__DRIdrawable *dPriv, void *data, unsigned width)
+put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
 {
    __DRIscreen *sPriv = dPriv->driScreenPriv;
    const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
 
    loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
-                    0, 0, width, dPriv->h,
+                    0, 0, width, height,
                     data, dPriv->loaderPrivate);
 }
 
 void
-drisw_update_drawable_info(__DRIdrawable *dPriv)
+drisw_update_drawable_info(struct dri_drawable *drawable)
 {
+   __DRIdrawable *dPriv = drawable->dPriv;
+
    get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
 }
 
+static void
+drisw_put_image(struct dri_drawable *drawable,
+                void *data, unsigned width, unsigned height)
+{
+   __DRIdrawable *dPriv = drawable->dPriv;
+
+   put_image(dPriv, data, width, height);
+}
+
 static INLINE void
 drisw_present_texture(__DRIdrawable *dPriv,
                       struct pipe_texture *ptex)
 {
    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct dri_screen *screen = dri_screen(drawable->sPriv);
-   struct pipe_context *pipe;
    struct pipe_surface *psurf;
-   struct pipe_transfer *ptrans;
-   void *pmap;
-   unsigned width;
 
-   pipe = dri1_get_pipe_context(screen);
    psurf = dri1_get_pipe_surface(drawable, ptex);
-   if (!pipe || !psurf)
+   if (!psurf)
       return;
 
-   ptrans = pipe->get_tex_transfer(pipe, ptex, 0, 0, 0,
-                                   PIPE_TRANSFER_READ,
-                                   0, 0, dPriv->w, dPriv->h);
-
-   width = ptrans->stride / util_format_get_blocksize(ptex->format);
-
-   pmap = pipe->transfer_map(pipe, ptrans);
-
-   assert(pmap);
-
-   put_image(dPriv, pmap, width);
-
-   pipe->transfer_unmap(pipe, ptrans);
-
-   pipe->tex_transfer_destroy(pipe, ptrans);
+   screen->pipe_screen->flush_frontbuffer(screen->pipe_screen, psurf, drawable);
 }
 
 static INLINE void
@@ -163,38 +130,38 @@ drisw_copy_to_front(__DRIdrawable * dPriv,
  */
 
 void
-drisw_flush_frontbuffer(struct dri_drawable *drawable,
-                        enum st_attachment_type statt)
+drisw_swap_buffers(__DRIdrawable *dPriv)
 {
    struct dri_context *ctx = dri_get_current();
+   struct dri_drawable *drawable = dri_drawable(dPriv);
    struct pipe_texture *ptex;
 
    if (!ctx)
       return;
 
-   ptex = drawable->textures[statt];
+   ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
 
    if (ptex) {
-      drisw_copy_to_front(ctx->dPriv, ptex);
+      ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+      drisw_copy_to_front(dPriv, ptex);
    }
 }
 
 void
-drisw_swap_buffers(__DRIdrawable *dPriv)
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+                        enum st_attachment_type statt)
 {
    struct dri_context *ctx = dri_get_current();
-   struct dri_drawable *drawable = dri_drawable(dPriv);
    struct pipe_texture *ptex;
 
    if (!ctx)
       return;
 
-   ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
+   ptex = drawable->textures[statt];
 
    if (ptex) {
-      ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
-
-      drisw_copy_to_front(dPriv, ptex);
+      drisw_copy_to_front(ctx->dPriv, ptex);
    }
 }
 
@@ -286,12 +253,16 @@ static const __DRIextension *drisw_screen_extensions[] = {
    NULL
 };
 
+static struct drisw_loader_funcs drisw_lf = {
+   .put_image = drisw_put_image
+};
+
 const __DRIconfig **
 drisw_init_screen(__DRIscreen * sPriv)
 {
    const __DRIconfig **configs;
    struct dri_screen *screen;
-   struct drm_create_screen_arg arg;
+   struct drisw_create_screen_arg arg;
 
    screen = CALLOC_STRUCT(dri_screen);
    if (!screen)
@@ -304,9 +275,10 @@ drisw_init_screen(__DRIscreen * sPriv)
    sPriv->private = (void *)screen;
    sPriv->extensions = drisw_screen_extensions;
 
-   arg.mode = DRM_CREATE_DRISW;
+   arg.base.mode = DRM_CREATE_DRISW;
+   arg.lf = &drisw_lf;
 
-   configs = dri_init_screen_helper(screen, &arg, 32);
+   configs = dri_init_screen_helper(screen, &arg.base, 32);
    if (!configs)
       goto fail;
 
index 2c0d5610facfa3787d908d06929511ed6f786c2f..c0c874f7326a7229a902e8eb240253d3b0f60fa1 100644 (file)
@@ -39,7 +39,7 @@ const __DRIconfig **
 drisw_init_screen(__DRIscreen * sPriv);
 
 void
-drisw_update_drawable_info(__DRIdrawable *dPriv);
+drisw_update_drawable_info(struct dri_drawable *drawable);
 
 void
 drisw_flush_frontbuffer(struct dri_drawable *drawable,
index 1f24d7650d70ca82babc5d0c1f47903276c0ac6d..63b935bb07b52d327f2a4c16940d04cb9d8c7a0c 100644 (file)
 #include "state_tracker/sw_winsys.h"
 #include "dri_sw_winsys.h"
 
-/* Copied from targets/libgl-xlib.
- *
- * TODO:
- * This function should be put in targets/common or winsys/sw/common and shared
- * with targets/libgl-xlib and winsys/sw/drm.
- *
- * For targets/common, you get layering violations unless all of drm_api's are
- * moved under targets.
- */
+/* Copied from targets/libgl-xlib */
 
 #ifdef GALLIUM_SOFTPIPE
 #include "softpipe/sp_public.h"
@@ -98,19 +90,24 @@ swrast_drm_create_screen(struct drm_api *api,
 {
    struct sw_winsys *winsys = NULL;
    struct pipe_screen *screen = NULL;
+   struct drisw_create_screen_arg *drisw;
 
    (void) drmFD;
 
    if (arg != NULL) {
       switch(arg->mode) {
       case DRM_CREATE_DRISW:
+         drisw = (struct drisw_create_screen_arg *)arg;
          break;
       default:
          return NULL;
       }
    }
+   else {
+      return NULL;
+   }
 
-   winsys = dri_create_sw_winsys();
+   winsys = dri_create_sw_winsys(drisw->lf);
    if (winsys == NULL)
       return NULL;
 
index 4a8366280d8686b76747857650963d5643bc89a3..48e5bdff4293387af85f97184747a50a2c9a0168 100644 (file)
@@ -55,6 +55,14 @@ PUBLIC const struct st_module st_module_OpenGL = {
  * GALLIUM_CELL, etc.  Scons already eliminates those #defines, so
  * things that are painful for it now are likely to be painful for
  * other build systems in the future.
+ *
+ * Copies (full or partial):
+ *    targets/libgl-xlib
+ *    targets/graw-xlib
+ *    targets/dri-swrast
+ *    winsys/sw/drm
+ *    drivers/sw
+ *
  */
 
 #ifdef GALLIUM_SOFTPIPE
index fb4722fc75faa352f5a4ab7a0b49762a082fbd3c..870c6afc1245d5d4df5d7cb1a91863db80762609 100644 (file)
 
 struct dri_sw_displaytarget
 {
+   enum pipe_format format;
+   unsigned width;
+   unsigned height;
+   unsigned stride;
+
    void *data;
    void *mapped;
 };
@@ -46,6 +51,8 @@ struct dri_sw_displaytarget
 struct dri_sw_winsys
 {
    struct sw_winsys base;
+
+   struct drisw_loader_funcs *lf;
 };
 
 static INLINE struct dri_sw_displaytarget *
@@ -79,23 +86,27 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
                             unsigned *stride)
 {
    struct dri_sw_displaytarget *dri_sw_dt;
-   unsigned nblocksy, size, dri_sw_stride, format_stride;
+   unsigned nblocksy, size, format_stride;
 
    dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
    if(!dri_sw_dt)
       goto no_dt;
 
+   dri_sw_dt->format = format;
+   dri_sw_dt->width = width;
+   dri_sw_dt->height = height;
+
    format_stride = util_format_get_stride(format, width);
-   dri_sw_stride = align(format_stride, alignment);
+   dri_sw_dt->stride = align(format_stride, alignment);
 
    nblocksy = util_format_get_nblocksy(format, height);
-   size = dri_sw_stride * nblocksy;
+   size = dri_sw_dt->stride * nblocksy;
 
    dri_sw_dt->data = align_malloc(size, alignment);
    if(!dri_sw_dt->data)
       goto no_data;
 
-   *stride = dri_sw_stride;
+   *stride = dri_sw_dt->stride;
    return (struct sw_displaytarget *)dri_sw_dt;
 
 no_data:
@@ -159,7 +170,20 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
                              struct sw_displaytarget *dt,
                              void *context_private)
 {
-   assert(0);
+   struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
+   struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+   struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
+   unsigned width, height;
+
+   /* Set the width to 'stride / cpp'.
+    *
+    * PutImage correctly clips to the width of the dst drawable.
+    */
+   width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
+
+   height = dri_sw_dt->height;
+
+   dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
 }
 
 
@@ -170,7 +194,7 @@ dri_destroy_sw_winsys(struct sw_winsys *winsys)
 }
 
 struct sw_winsys *
-dri_create_sw_winsys(void)
+dri_create_sw_winsys(struct drisw_loader_funcs *lf)
 {
    struct dri_sw_winsys *ws;
 
@@ -178,6 +202,7 @@ dri_create_sw_winsys(void)
    if (!ws)
       return NULL;
 
+   ws->lf = lf;
    ws->base.destroy = dri_destroy_sw_winsys;
 
    ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported;
index c2382a68d78f41ec12670eef1e48bb1090f36b9e..329ac06a05b985ef6c6a80b2ba818a57f5718cf2 100644 (file)
 #ifndef DRI_SW_WINSYS
 #define DRI_SW_WINSYS
 
+#include "state_tracker/drisw_api.h"
+
 struct sw_winsys;
 
-struct sw_winsys *dri_create_sw_winsys(void);
+struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf);
 
 #endif