st/vega: Delay fb state update to vg_validate_state.
authorChia-I Wu <olv@lunarg.com>
Sat, 27 Nov 2010 14:05:37 +0000 (22:05 +0800)
committerChia-I Wu <olv@lunarg.com>
Wed, 1 Dec 2010 03:23:49 +0000 (11:23 +0800)
vg_manager_validate_framebuffer should mark the fb dirty and have
vg_validate_state call cso_set_framebuffer.  Rename VIEWPORT_DIRTY to
FRAMEBUFFER_DIRTY.

src/gallium/state_trackers/vega/vg_context.c
src/gallium/state_trackers/vega/vg_context.h
src/gallium/state_trackers/vega/vg_manager.c

index d534783..037505e 100644 (file)
@@ -387,27 +387,45 @@ void vg_validate_state(struct vg_context *ctx)
       raster->gl_rasterization_rules = 1;
       cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer);
    }
-   if ((ctx->state.dirty & VIEWPORT_DIRTY)) {
+   if ((ctx->state.dirty & FRAMEBUFFER_DIRTY)) {
       struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
-      const VGint param_bytes = 8 * sizeof(VGfloat);
-      VGfloat vs_consts[8] = {
-         2.f/fb->width, 2.f/fb->height, 1, 1,
-         -1, -1, 0, 0
-      };
       struct pipe_resource **cbuf = &ctx->vs_const_buffer;
+      VGfloat vs_consts[8];
 
+      memset(fb, 0, sizeof(struct pipe_framebuffer_state));
+      fb->width  = ctx->draw_buffer->width;
+      fb->height = ctx->draw_buffer->height;
+      fb->nr_cbufs = 1;
+      fb->cbufs[0] = ctx->draw_buffer->strb->surface;
+      fb->zsbuf = ctx->draw_buffer->dsrb->surface;
+
+      cso_set_framebuffer(ctx->cso_context, fb);
       vg_set_viewport(ctx, VEGA_Y0_BOTTOM);
 
+      /* surface coordinates to clipped coordinates */
+      vs_consts[0] = 2.0f / fb->width;
+      vs_consts[1] = 2.0f / fb->height;
+      vs_consts[2] = 1.0f;
+      vs_consts[3] = 1.0f;
+      vs_consts[4] = -1.0f;
+      vs_consts[5] = -1.0f;
+      vs_consts[6] = 0.0f;
+      vs_consts[7] = 0.0f;
+
       pipe_resource_reference(cbuf, NULL);
       *cbuf = pipe_buffer_create(ctx->pipe->screen, 
                                 PIPE_BIND_CONSTANT_BUFFER,
-                                param_bytes);
+                                sizeof(vs_consts));
 
       if (*cbuf) {
          st_no_flush_pipe_buffer_write(ctx, *cbuf,
-                                       0, param_bytes, vs_consts);
+                                       0, sizeof(vs_consts), vs_consts);
       }
       ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf);
+
+      /* we also got a new depth buffer */
+      if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY))
+         ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
    }
    if ((ctx->state.dirty & VS_DIRTY)) {
       cso_set_vertex_shader_handle(ctx->cso_context,
index 80a6c07..547674b 100644 (file)
@@ -81,11 +81,11 @@ enum dirty_state {
    NONE_DIRTY          = 0<<0,
    BLEND_DIRTY         = 1<<1,
    RASTERIZER_DIRTY    = 1<<2,
-   VIEWPORT_DIRTY      = 1<<3,
+   FRAMEBUFFER_DIRTY   = 1<<3,
    VS_DIRTY            = 1<<4,
    DEPTH_STENCIL_DIRTY = 1<<5,
    ALL_DIRTY           = BLEND_DIRTY | RASTERIZER_DIRTY |
-   VIEWPORT_DIRTY | VS_DIRTY | DEPTH_STENCIL_DIRTY
+   FRAMEBUFFER_DIRTY | VS_DIRTY | DEPTH_STENCIL_DIRTY
 };
 
 struct vg_context
index bb15ec0..9254d7d 100644 (file)
@@ -97,10 +97,17 @@ create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
 }
 
 static void
-setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb)
+vg_context_update_alpha_mask_view(struct vg_context *ctx,
+                                  uint width, uint height)
 {
-   struct pipe_context *pipe = ctx->pipe;
+   struct st_framebuffer *stfb = ctx->draw_buffer;
    struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view;
+   struct pipe_context *pipe = ctx->pipe;
+
+   if (old_sampler_view &&
+       old_sampler_view->texture->width0 == width &&
+       old_sampler_view->texture->height0 == height)
+      return;
 
    /*
      we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
@@ -108,7 +115,7 @@ setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb)
      space it makes both of those a lot simpler
    */
    stfb->alpha_mask_view = create_tex_and_view(pipe,
-         PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height);
+         PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
 
    if (!stfb->alpha_mask_view) {
       if (old_sampler_view)
@@ -120,7 +127,7 @@ setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb)
    vg_validate_state(ctx);
 
    /* alpha mask starts with 1.f alpha */
-   mask_fill(0, 0, stfb->width, stfb->height, 1.f);
+   mask_fill(0, 0, width, height, 1.f);
 
    /* if we had an old surface copy it over */
    if (old_sampler_view) {
@@ -148,6 +155,25 @@ setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb)
       pipe_sampler_view_reference(&old_sampler_view, NULL);
 }
 
+static void
+vg_context_update_blend_texture_view(struct vg_context *ctx,
+                                     uint width, uint height)
+{
+   struct pipe_context *pipe = ctx->pipe;
+   struct st_framebuffer *stfb = ctx->draw_buffer;
+   struct pipe_sampler_view *old = stfb->blend_texture_view;
+
+   if (old &&
+       old->texture->width0 == width &&
+       old->texture->height0 == height)
+      return;
+
+   stfb->blend_texture_view = create_tex_and_view(pipe,
+         PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+
+   pipe_sampler_view_reference(&old, NULL);
+}
+
 static boolean
 vg_context_update_depth_stencil_rb(struct vg_context * ctx,
                                    uint width, uint height)
@@ -220,49 +246,6 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
    return TRUE;
 }
 
-static void
-vg_context_update_draw_buffer(struct vg_context *ctx, struct pipe_resource *pt)
-{
-   struct st_framebuffer *stfb = ctx->draw_buffer;
-   boolean new_cbuf, new_zsbuf, new_size;
-
-   new_cbuf = vg_context_update_color_rb(ctx, pt);
-   new_zsbuf =
-      vg_context_update_depth_stencil_rb(ctx, pt->width0, pt->height0);
-
-   new_size = (stfb->width != pt->width0 || stfb->height != pt->height0);
-   stfb->width = pt->width0;
-   stfb->height = pt->height0;
-
-   if (new_cbuf || new_zsbuf || new_size) {
-      struct pipe_framebuffer_state *state = &ctx->state.g3d.fb;
-
-      memset(state, 0, sizeof(struct pipe_framebuffer_state));
-      state->width  = stfb->width;
-      state->height = stfb->height;
-      state->nr_cbufs = 1;
-      state->cbufs[0] = stfb->strb->surface;
-      state->zsbuf = stfb->dsrb->surface;
-
-      cso_set_framebuffer(ctx->cso_context, state);
-   }
-
-   if (new_zsbuf || new_size) {
-      ctx->state.dirty |= VIEWPORT_DIRTY;
-      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;/*to reset the scissors*/
-
-      ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
-
-      /* we need all the other state already set */
-
-      setup_new_alpha_mask(ctx, stfb);
-
-      pipe_sampler_view_reference( &stfb->blend_texture_view, NULL);
-      stfb->blend_texture_view = create_tex_and_view(ctx->pipe,
-            PIPE_FORMAT_B8G8R8A8_UNORM, stfb->width, stfb->height);
-   }
-}
-
 /**
  * Flush the front buffer if the current context renders to the front buffer.
  */
@@ -304,15 +287,23 @@ vg_manager_validate_framebuffer(struct vg_context *ctx)
    if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
       return;
 
-   /*
-    * unset draw_buffer_invalid first because vg_context_update_draw_buffer
-    * will cause the framebuffer to be validated again because of a call to
-    * vg_validate_state
-    */
    p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
-   vg_context_update_draw_buffer(ctx, pt);
-}
 
+   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_depth_stencil_rb(ctx, pt->width0, pt->height0))
+      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
+
+   stfb->width = pt->width0;
+   stfb->height = pt->height0;
+
+   /* TODO create as needed */
+   vg_context_update_alpha_mask_view(ctx, stfb->width, stfb->height);
+   vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height);
+}
 
 static void
 vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,