[Mesa-dev] [PATCH 1/2] st-api: Rework how drawables are invalidated

Chia-I Wu olv at lunarg.com
Tue Jun 28 16:26:58 PDT 2011


On Tue, Jun 28, 2011 at 9:19 PM, Thomas Hellstrom <thellstrom at vmware.com> wrote:
> The api and the state tracker manager code as well as the state tracker code
> assumed that only a single context could be bound to a drawable. That is not
> a valid assumption, since multiple contexts can bind to the same drawable.
>
> Fix this by making it the state tracker's responsibility to update all
> contexts binding to a drawable.
This looks great.

Just one question.  Would it make things easier for mesa and vega if
we have st_framebuffer_iface::stamp instead of
st_framebuffer_iface::invalid?

> Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
> ---
>  src/gallium/include/state_tracker/st_api.h         |   26 ++-----
>  .../state_trackers/dri/common/dri_drawable.c       |    3 +
>  src/gallium/state_trackers/dri/drm/dri2.c          |    4 +-
>  src/gallium/state_trackers/dri/sw/drisw.c          |    4 +-
>  src/gallium/state_trackers/egl/common/egl_g3d.c    |   12 +--
>  .../state_trackers/egl/common/egl_g3d_api.c        |    7 --
>  src/gallium/state_trackers/egl/common/egl_g3d_st.c |    8 ++
>  src/gallium/state_trackers/vega/vg_context.h       |    4 +-
>  src/gallium/state_trackers/vega/vg_manager.c       |   40 ++++------
>  src/gallium/state_trackers/wgl/stw_context.c       |    6 +-
>  src/gallium/state_trackers/wgl/stw_st.c            |    3 +
>  src/mesa/state_tracker/st_cb_viewport.c            |   15 +++-
>  src/mesa/state_tracker/st_context.h                |    5 +-
>  src/mesa/state_tracker/st_manager.c                |   85 +++++++++++---------
>  14 files changed, 109 insertions(+), 113 deletions(-)
>
> diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
> index 04fc7c6..b08972f 100644
> --- a/src/gallium/include/state_tracker/st_api.h
> +++ b/src/gallium/include/state_tracker/st_api.h
> @@ -253,6 +253,13 @@ struct st_context_attribs
>  struct st_framebuffer_iface
>  {
>    /**
> +    * Atomic flag to indicate invalid status, which can only be resolved
> +    * by a call to validate.
> +    */
> +
> +   int32_t invalid;
> +
> +   /**
>     * Available for the state tracker manager to use.
>     */
>    void *st_manager_private;
> @@ -315,25 +322,6 @@ struct st_context_iface
>    void (*destroy)(struct st_context_iface *stctxi);
>
>    /**
> -    * Invalidate the current textures that was taken from a framebuffer.
> -    *
> -    * The state tracker manager calls this function to let the rendering
> -    * context know that it should update the textures it got from
> -    * st_framebuffer_iface::validate.  It should do so at the latest time possible.
> -    * Possible right before sending triangles to the pipe context.
> -    *
> -    * For certain platforms this function might be called from a thread other
> -    * than the thread that the context is currently bound in, and must
> -    * therefore be thread safe. But it is the state tracker manager's
> -    * responsibility to make sure that the framebuffer is bound to the context
> -    * and the API context is current for the duration of this call.
> -    *
> -    * Thus reducing the sync primitive needed to a single atomic flag.
> -    */
> -   void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi,
> -                                      struct st_framebuffer_iface *stfbi);
> -
> -   /**
>     * Flush all drawing from context to the pipe also flushes the pipe.
>     */
>    void (*flush)(struct st_context_iface *stctxi, unsigned flags,
> diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
> index 28a33ac..09d25bc 100644
> --- a/src/gallium/state_trackers/dri/common/dri_drawable.c
> +++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
> @@ -82,6 +82,8 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
>       drawable->texture_mask = statt_mask;
>    }
>
> +   p_atomic_set(&drawable->base.invalid, FALSE);
> +
>    if (!out)
>       return TRUE;
>
> @@ -136,6 +138,7 @@ dri_create_buffer(__DRIscreen * sPriv,
>    drawable->sPriv = sPriv;
>    drawable->dPriv = dPriv;
>    dPriv->driverPrivate = (void *)drawable;
> +   p_atomic_set(&drawable->base.invalid, TRUE);
>
>    return GL_TRUE;
>  fail:
> diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
> index e471e8e..9e61d7e 100644
> --- a/src/gallium/state_trackers/dri/drm/dri2.c
> +++ b/src/gallium/state_trackers/dri/drm/dri2.c
> @@ -52,13 +52,11 @@ static void
>  dri2_invalidate_drawable(__DRIdrawable *dPriv)
>  {
>    struct dri_drawable *drawable = dri_drawable(dPriv);
> -   struct dri_context *ctx = drawable->context;
>
>    dri2InvalidateDrawable(dPriv);
>    drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
>
> -   if (ctx)
> -      ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base);
> +   p_atomic_set(&drawable->base.invalid, TRUE);
>  }
>
>  static const __DRI2flushExtension dri2FlushExtension = {
> diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
> index ac11f7c..f9ba971 100644
> --- a/src/gallium/state_trackers/dri/sw/drisw.c
> +++ b/src/gallium/state_trackers/dri/sw/drisw.c
> @@ -108,9 +108,7 @@ drisw_invalidate_drawable(__DRIdrawable *dPriv)
>
>    drawable->texture_stamp = dPriv->lastStamp - 1;
>
> -   /* check if swapping currently bound buffer */
> -   if (ctx && ctx->dPriv == dPriv)
> -      ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base);
> +   p_atomic_set(&drawable->base.invalid, TRUE);
>  }
>
>  static INLINE void
> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
> index 29dbbef..45db90a 100644
> --- a/src/gallium/state_trackers/egl/common/egl_g3d.c
> +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
> @@ -45,15 +45,9 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
>  {
>    /* XXX not thread safe? */
>    struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
> -   struct egl_g3d_context *gctx;
> -
> -   /*
> -    * Some functions such as egl_g3d_copy_buffers create a temporary native
> -    * surface.  There is no gsurf associated with it.
> -    */
> -   gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
> -   if (gctx)
> -      gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
> +
> +   if (gsurf && gsurf->stfbi)
> +      p_atomic_set(&gsurf->stfbi->invalid, TRUE);
>  }
>
>  static struct pipe_screen *
> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
> index 8b1821e..f0d6d71 100644
> --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
> +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
> @@ -536,19 +536,12 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
>             (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
>       if (ok) {
>          if (gdraw) {
> -            gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
> -                  gdraw->stfbi);
> -
>             if (gdraw->base.Type == EGL_WINDOW_BIT) {
>                gctx->base.WindowRenderBuffer =
>                   (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
>                   EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
>             }
>          }
> -         if (gread && gread != gdraw) {
> -            gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
> -                  gread->stfbi);
> -         }
>       }
>    }
>    else if (old_gctx) {
> diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
> index 2b944b5..cb9c237 100644
> --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
> +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
> @@ -182,6 +182,9 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
>       pipe_resource_reference(&out[i], gsurf->render_texture);
>    }
>
> +   if (gsurf->stfbi)
> +      p_atomic_set(&gsurf->stfbi->invalid, FALSE);
> +
>    return TRUE;
>  }
>
> @@ -278,6 +281,9 @@ egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
>       }
>    }
>
> +   if (gsurf->stfbi)
> +      p_atomic_set(&gsurf->stfbi->invalid, FALSE);
> +
>    return TRUE;
>  }
>
> @@ -292,6 +298,8 @@ egl_g3d_create_st_framebuffer(_EGLSurface *surf)
>       return NULL;
>
>    stfbi->visual = &gsurf->stvis;
> +   p_atomic_set(&stfbi->invalid, TRUE);
> +
>    if (gsurf->base.Type != EGL_PBUFFER_BIT) {
>       stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
>       stfbi->validate = egl_g3d_st_framebuffer_validate;
> diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
> index 71491a5..0d91007 100644
> --- a/src/gallium/state_trackers/vega/vg_context.h
> +++ b/src/gallium/state_trackers/vega/vg_context.h
> @@ -65,6 +65,7 @@ struct st_framebuffer {
>    enum st_attachment_type strb_att;
>
>    void *privateData;
> +   int32_t stamp;
>  };
>
>  enum vg_object_type {
> @@ -105,7 +106,6 @@ struct vg_context
>    VGErrorCode _error;
>
>    struct st_framebuffer *draw_buffer;
> -   int32_t draw_buffer_invalid;
>
>    struct cso_hash *owned_objects[VG_OBJECT_LAST];
>
> @@ -129,6 +129,8 @@ struct vg_context
>    struct vg_paint *default_paint;
>
>    struct blit_state *blit;
> +
> +   int32_t draw_stamp;
>  };
>
>
> diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
> index eeea686..c9149f8 100644
> --- a/src/gallium/state_trackers/vega/vg_manager.c
> +++ b/src/gallium/state_trackers/vega/vg_manager.c
> @@ -111,30 +111,25 @@ vg_manager_validate_framebuffer(struct vg_context *ctx)
>    if (!stfb)
>       return;
>
> -   if (!p_atomic_read(&ctx->draw_buffer_invalid))
> -      return;
> -
> -   /* validate the fb */
> -   if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
> -      return;
> +   if (p_atomic_read(&stfb->iface->invalid)) {
>
> -   p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
> +      /* validate the fb */
> +      if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
> +         return;
>
> -   if (vg_context_update_color_rb(ctx, pt) ||
> -       stfb->width != pt->width0 ||
> -       stfb->height != pt->height0)
> -      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
> +      if (vg_context_update_color_rb(ctx, pt) ||
> +          stfb->width != pt->width0 ||
> +          stfb->height != pt->height0)
> +         ++stfb->stamp;
>
> -   stfb->width = pt->width0;
> -   stfb->height = pt->height0;
> -}
> +      stfb->width = pt->width0;
> +      stfb->height = pt->height0;
> +   }
>
> -static void
> -vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
> -                                      struct st_framebuffer_iface *stfbi)
> -{
> -   struct vg_context *ctx = (struct vg_context *) stctxi;
> -   p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
> +   if (ctx->draw_stamp != stfb->stamp) {
> +      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
> +      ctx->draw_stamp = stfb->stamp;
> +   }
>  }
>
>  static void
> @@ -187,8 +182,6 @@ vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
>
>    ctx->iface.destroy = vg_context_destroy;
>
> -   ctx->iface.notify_invalid_framebuffer =
> -      vg_context_notify_invalid_framebuffer;
>    ctx->iface.flush = vg_context_flush;
>
>    ctx->iface.teximage = NULL;
> @@ -266,8 +259,6 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
>    if (stdrawi != streadi)
>       return FALSE;
>
> -   p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
> -
>    strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
>
>    if (ctx->draw_buffer) {
> @@ -318,6 +309,7 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
>    }
>
>    ctx->draw_buffer->iface = stdrawi;
> +   ctx->draw_stamp = ctx->draw_buffer->stamp - 1;
>
>    return TRUE;
>  }
> diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
> index 5608d4f..7e29960 100644
> --- a/src/gallium/state_trackers/wgl/stw_context.c
> +++ b/src/gallium/state_trackers/wgl/stw_context.c
> @@ -31,6 +31,7 @@
>  #include "pipe/p_context.h"
>  #include "pipe/p_state.h"
>  #include "util/u_memory.h"
> +#include "util/u_atomic.h"
>  #include "state_tracker/st_api.h"
>
>  #include "stw_icd.h"
> @@ -361,10 +362,7 @@ stw_flush_current_locked( struct stw_framebuffer *fb )
>  void
>  stw_notify_current_locked( struct stw_framebuffer *fb )
>  {
> -   struct stw_context *ctx = stw_current_context();
> -
> -   if (ctx && ctx->current_framebuffer == fb)
> -      ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb);
> +   p_atomic_set(&fb->stfb->invalid, TRUE);
>  }
>
>  /**
> diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
> index 9174533..7299441 100644
> --- a/src/gallium/state_trackers/wgl/stw_st.c
> +++ b/src/gallium/state_trackers/wgl/stw_st.c
> @@ -27,6 +27,7 @@
>
>  #include "util/u_memory.h"
>  #include "util/u_inlines.h"
> +#include "util/u_atomic.h"
>  #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
>
>  #include "stw_st.h"
> @@ -117,6 +118,7 @@ stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb,
>    stwfb->texture_width = width;
>    stwfb->texture_height = height;
>    stwfb->texture_mask = mask;
> +   p_atomic_set(&stfb->invalid, FALSE);
>  }
>
>  static boolean
> @@ -196,6 +198,7 @@ stw_st_create_framebuffer(struct stw_framebuffer *fb)
>    stwfb->stvis = fb->pfi->stvis;
>
>    stwfb->base.visual = &stwfb->stvis;
> +   p_atomic_set(&stwfb->base.invalid, TRUE);
>    stwfb->base.flush_front = stw_st_framebuffer_flush_front;
>    stwfb->base.validate = stw_st_framebuffer_validate;
>
> diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c
> index 049755e..c74d013 100644
> --- a/src/mesa/state_tracker/st_cb_viewport.c
> +++ b/src/mesa/state_tracker/st_cb_viewport.c
> @@ -56,13 +56,20 @@ static void st_viewport(struct gl_context * ctx, GLint x, GLint y,
>    if (!st->invalidate_on_gl_viewport)
>       return;
>
> +   /*
> +    * Normally we'd want the state tracker manager to mark the drawables
> +    * invalid only when needed. This will force the state tracker manager
> +    * to revalidate the drawable, rather than just update the context with
> +    * the latest cached drawable info.
> +    */
> +
>    stdraw = st_ws_framebuffer(st->ctx->DrawBuffer);
>    stread = st_ws_framebuffer(st->ctx->ReadBuffer);
>
> -   if (stdraw)
> -      p_atomic_set(&stdraw->revalidate, TRUE);
> -   if (stread && stread != stdraw)
> -      p_atomic_set(&stread->revalidate, TRUE);
> +   if (stdraw && stdraw->iface)
> +       p_atomic_set(&stdraw->iface->invalid, TRUE);
> +   if (stread && stread != stdraw && stread->iface)
> +       p_atomic_set(&stread->iface->invalid, TRUE);
>  }
>
>  void st_init_viewport_functions(struct dd_function_table *functions)
> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
> index ff20703..f76fae3 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -204,6 +204,9 @@ struct st_context
>    /* Active render condition. */
>    struct pipe_query *render_condition;
>    unsigned condition_mode;
> +
> +   int32_t draw_stamp;
> +   int32_t read_stamp;
>  };
>
>
> @@ -227,7 +230,7 @@ struct st_framebuffer
>    struct st_framebuffer_iface *iface;
>    enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
>    unsigned num_statts;
> -   int32_t revalidate;
> +   int32_t stamp;
>  };
>
>
> diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
> index a68544d..cc688a3 100644
> --- a/src/mesa/state_tracker/st_manager.c
> +++ b/src/mesa/state_tracker/st_manager.c
> @@ -139,18 +139,52 @@ buffer_index_to_attachment(gl_buffer_index index)
>  }
>
>  /**
> + * Make sure a context picks up the latest cached state of the
> + * drawables it binds to.
> + */
> +static void
> +st_context_validate(struct st_context *st,
> +                    struct st_framebuffer *stdraw,
> +                    struct st_framebuffer *stread)
> +{
> +    if (stdraw && stdraw->stamp != st->draw_stamp) {
> +       st->dirty.st |= ST_NEW_FRAMEBUFFER;
> +       _mesa_resize_framebuffer(st->ctx, &stdraw->Base,
> +                                stdraw->Base.Width,
> +                                stdraw->Base.Height);
> +       st->draw_stamp = stdraw->stamp;
> +    }
> +
> +    if (stread && stread->stamp != st->read_stamp) {
> +       if (stread != stdraw) {
> +          st->dirty.st |= ST_NEW_FRAMEBUFFER;
> +          _mesa_resize_framebuffer(st->ctx, &stread->Base,
> +                                   stread->Base.Width,
> +                                   stread->Base.Height);
> +       }
> +       st->read_stamp = stread->stamp;
> +    }
> +}
> +
> +/**
>  * Validate a framebuffer to make sure up-to-date pipe_textures are used.
> + * The context we need to pass in is s dummy context needed only to be
> + * able to get a pipe context to create pipe surfaces, and to have a
> + * context to call _mesa_resize_framebuffer():
> + * (That should probably be rethought, since those surfaces become
> + * drawable state, not context state, and can be freed by another pipe
> + * context).
>  */
>  static void
> -st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
> +st_framebuffer_validate(struct st_framebuffer *stfb,
> +                        struct st_context *st)
>  {
> -   struct pipe_context *pipe = st->pipe;
>    struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
>    uint width, height;
>    unsigned i;
>    boolean changed = FALSE;
>
> -   if (!p_atomic_read(&stfb->revalidate))
> +   if (!p_atomic_read(&stfb->iface->invalid))
>       return;
>
>    /* validate the fb */
> @@ -184,7 +218,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
>       memset(&surf_tmpl, 0, sizeof(surf_tmpl));
>       u_surface_default_template(&surf_tmpl, textures[i],
>                                  PIPE_BIND_RENDER_TARGET);
> -      ps = pipe->create_surface(pipe, textures[i], &surf_tmpl);
> +      ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl);
>       if (ps) {
>          pipe_surface_reference(&strb->surface, ps);
>          pipe_resource_reference(&strb->texture, ps->texture);
> @@ -204,14 +238,9 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
>    }
>
>    if (changed) {
> -      st->dirty.st |= ST_NEW_FRAMEBUFFER;
> +      ++stfb->stamp;
>       _mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height);
> -
> -      assert(stfb->Base.Width == width);
> -      assert(stfb->Base.Height == height);
>    }
> -
> -   p_atomic_set(&stfb->revalidate, FALSE);
>  }
>
>  /**
> @@ -237,7 +266,7 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb)
>          stfb->statts[stfb->num_statts++] = statt;
>    }
>
> -   p_atomic_set(&stfb->revalidate, TRUE);
> +   stfb->stamp = 0;
>  }
>
>  /**
> @@ -443,6 +472,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi)
>          &stfb->Base._ColorReadBufferIndex);
>
>    stfb->iface = stfbi;
> +   p_atomic_set(&stfbi->invalid, TRUE);
>
>    /* add the color buffer */
>    idx = stfb->Base._ColorDrawBufferIndexes[0];
> @@ -473,31 +503,6 @@ st_framebuffer_reference(struct st_framebuffer **ptr,
>  }
>
>  static void
> -st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
> -                                      struct st_framebuffer_iface *stfbi)
> -{
> -   struct st_context *st = (struct st_context *) stctxi;
> -   struct st_framebuffer *stfb;
> -
> -   /* either draw or read winsys fb */
> -   stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer);
> -   if (!stfb || stfb->iface != stfbi)
> -      stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer);
> -
> -   if (stfb && stfb->iface == stfbi) {
> -      p_atomic_set(&stfb->revalidate, TRUE);
> -   }
> -   else {
> -      /* This function is probably getting called when we've detected a
> -       * change in a window's size but the currently bound context is
> -       * not bound to that window.
> -       * If the st_framebuffer_iface structure had a pointer to the
> -       * corresponding st_framebuffer we'd be able to handle this.
> -       */
> -   }
> -}
> -
> -static void
>  st_context_flush(struct st_context_iface *stctxi, unsigned flags,
>                  struct pipe_fence_handle **fence)
>  {
> @@ -696,8 +701,6 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
>       smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE);
>
>    st->iface.destroy = st_context_destroy;
> -   st->iface.notify_invalid_framebuffer =
> -      st_context_notify_invalid_framebuffer;
>    st->iface.flush = st_context_flush;
>    st->iface.teximage = st_context_teximage;
>    st->iface.copy = st_context_copy;
> @@ -757,6 +760,10 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
>          }
>
>          ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base);
> +
> +         st->draw_stamp = stdraw->stamp - 1;
> +         st->read_stamp = stread->stamp - 1;
> +         st_context_validate(st, stdraw, stread);
>       }
>       else {
>          struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer();
> @@ -857,6 +864,8 @@ st_manager_validate_framebuffers(struct st_context *st)
>       st_framebuffer_validate(stdraw, st);
>    if (stread && stread != stdraw)
>       st_framebuffer_validate(stread, st);
> +
> +   st_context_validate(st, stdraw, stread);
>  }
>
>  /**
> --
> 1.7.4.4
>
>



-- 
olv at LunarG.com


More information about the mesa-dev mailing list