util: add version of u_blit_pixels which takes a writemask
authorKeith Whitwell <keithw@vmware.com>
Wed, 2 Sep 2009 16:58:52 +0000 (17:58 +0100)
committerBrian Paul <brianp@vmware.com>
Thu, 3 Sep 2009 22:07:45 +0000 (16:07 -0600)
Values outside the writemask are set in the destination to {0,0,0,1}

src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_blit.h
src/gallium/auxiliary/util/u_simple_shaders.c
src/gallium/auxiliary/util/u_simple_shaders.h

index cda6dbd46d76d06bae88e45ba79ec9c66bb6c993..c516317d701113638fa362f64cfa040daf6c70f1 100644 (file)
@@ -62,7 +62,7 @@ struct blit_state
    struct pipe_viewport_state viewport;
 
    void *vs;
-   void *fs;
+   void *fs[TGSI_WRITEMASK_XYZW + 1];
 
    struct pipe_buffer *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -125,7 +125,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
    }
 
    /* fragment shader */
-   ctx->fs = util_make_fragment_tex_shader(pipe);
+   ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
    ctx->vbuf = NULL;
 
    /* init vertex data that doesn't change */
@@ -146,9 +146,13 @@ void
 util_destroy_blit(struct blit_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
+   unsigned i;
 
    pipe->delete_vs_state(pipe, ctx->vs);
-   pipe->delete_fs_state(pipe, ctx->fs);
+
+   for (i = 0; i < Elements(ctx->fs); i++)
+      if (ctx->fs[i])
+         pipe->delete_fs_state(pipe, ctx->fs[i]);
 
    pipe_buffer_reference(&ctx->vbuf, NULL);
 
@@ -299,14 +303,15 @@ regions_overlap(int srcX0, int srcY0,
  * XXX need some control over blitting Z and/or stencil.
  */
 void
-util_blit_pixels(struct blit_state *ctx,
-                 struct pipe_surface *src,
-                 int srcX0, int srcY0,
-                 int srcX1, int srcY1,
-                 struct pipe_surface *dst,
-                 int dstX0, int dstY0,
-                 int dstX1, int dstY1,
-                 float z, uint filter)
+util_blit_pixels_writemask(struct blit_state *ctx,
+                           struct pipe_surface *src,
+                           int srcX0, int srcY0,
+                           int srcX1, int srcY1,
+                           struct pipe_surface *dst,
+                           int dstX0, int dstY0,
+                           int dstX1, int dstY1,
+                           float z, uint filter,
+                           uint writemask)
 {
    struct pipe_context *pipe = ctx->pipe;
    struct pipe_screen *screen = pipe->screen;
@@ -426,8 +431,11 @@ util_blit_pixels(struct blit_state *ctx,
    /* texture */
    cso_set_sampler_textures(ctx->cso, 1, &tex);
 
+   if (ctx->fs[writemask] == NULL)
+      ctx->fs[writemask] = util_make_fragment_tex_shader_writemask(pipe, writemask);
+
    /* shaders */
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
    cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
 
    /* drawing dest */
@@ -462,6 +470,27 @@ util_blit_pixels(struct blit_state *ctx,
 }
 
 
+void
+util_blit_pixels(struct blit_state *ctx,
+                 struct pipe_surface *src,
+                 int srcX0, int srcY0,
+                 int srcX1, int srcY1,
+                 struct pipe_surface *dst,
+                 int dstX0, int dstY0,
+                 int dstX1, int dstY1,
+                 float z, uint filter )
+{
+   util_blit_pixels_writemask( ctx, src, 
+                               srcX0, srcY0,
+                               srcX1, srcY1,
+                               dst,
+                               dstX0, dstY0,
+                               dstX1, dstY1,
+                               z, filter,
+                               TGSI_WRITEMASK_XYZW );
+}
+
+
 /* Release vertex buffer at end of frame to avoid synchronous
  * rendering.
  */
@@ -535,7 +564,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_set_sampler_textures(ctx->cso, 1, &tex);
 
    /* shaders */
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
    cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
 
    /* drawing dest */
index c35beceda8d64e986c847a61b29382ff573df565..a102021529e8209e42e1f4070a2c7b6e3bc97b94 100644 (file)
@@ -60,6 +60,17 @@ util_blit_pixels(struct blit_state *ctx,
                  int dstX1, int dstY1,
                  float z, uint filter);
 
+void
+util_blit_pixels_writemask(struct blit_state *ctx,
+                           struct pipe_surface *src,
+                           int srcX0, int srcY0,
+                           int srcX1, int srcY1,
+                           struct pipe_surface *dst,
+                           int dstX0, int dstY0,
+                           int dstX1, int dstY1,
+                           float z, uint filter,
+                           uint writemask);
+
 extern void
 util_blit_pixels_tex(struct blit_state *ctx,
                      struct pipe_texture *tex,
index eb311d29f9495d9cbc2adf7f4e94e1a16673796f..1b8da9b6853a2b16881972b9e5e3b19609e8a386 100644 (file)
@@ -88,11 +88,14 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
 
 /**
  * Make simple fragment texture shader:
- *  TEX OUT[0], IN[0], SAMP[0], 2D;
+ *  IMM {0,0,0,1}                         // (if writemask != 0xf)
+ *  MOV OUT[0], IMM[0]                    // (if writemask != 0xf)
+ *  TEX OUT[0].writemask, IN[0], SAMP[0], 2D;
  *  END;
  */
 void *
-util_make_fragment_tex_shader(struct pipe_context *pipe)
+util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
+                                        unsigned writemask )
 {
    struct ureg_program *ureg;
    struct ureg_src sampler;
@@ -119,6 +122,13 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
    return ureg_create_shader_and_destroy( ureg, pipe );
 }
 
+void *
+util_make_fragment_tex_shader(struct pipe_context *pipe )
+{
+   return util_make_fragment_tex_shader_writemask( pipe,
+                                                   TGSI_WRITEMASK_XYZW );
+}
+
 
 
 
index 6f8d96af9bcbf17526ce8032b20f915e373f64b8..d2e80d6eb4d1dcaf9c63ec09bd36288fc8d3200e 100644 (file)
@@ -49,6 +49,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
                                     const uint *semantic_indexes);
 
 
+extern void *
+util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, 
+                                        unsigned writemask );
+
 extern void *
 util_make_fragment_tex_shader(struct pipe_context *pipe);