Mesa (mesa_7_5_branch): util: add version of u_blit_pixels which takes a writemask

Keith Whitwell keithw at kemper.freedesktop.org
Wed Sep 2 17:42:31 UTC 2009


Module: Mesa
Branch: mesa_7_5_branch
Commit: de343680a3e6b2a588f8b3c844828b8d9e6cb6a5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=de343680a3e6b2a588f8b3c844828b8d9e6cb6a5

Author: Keith Whitwell <keithw at vmware.com>
Date:   Wed Sep  2 17:58:52 2009 +0100

util: add version of u_blit_pixels which takes a writemask

Values outside the writemask are set in the destination to {0,0,0,1}

---

 src/gallium/auxiliary/util/u_blit.c           |   55 +++++++++++++++++++------
 src/gallium/auxiliary/util/u_blit.h           |   11 +++++
 src/gallium/auxiliary/util/u_simple_shaders.c |   45 +++++++++++++++++++-
 src/gallium/auxiliary/util/u_simple_shaders.h |    4 ++
 4 files changed, 100 insertions(+), 15 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index cda6dbd..c516317 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -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 */
diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
index c35bece..a102021 100644
--- a/src/gallium/auxiliary/util/u_blit.h
+++ b/src/gallium/auxiliary/util/u_blit.h
@@ -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,
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index e519c35..acc5b83 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -152,11 +152,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 pipe_shader_state shader;
    struct tgsi_token tokens[100];
@@ -217,12 +220,43 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
                                      header,
                                      Elements(tokens) - ti);
 
+
+   if (writemask != TGSI_WRITEMASK_XYZW) {
+      struct tgsi_full_immediate imm;
+      static const float value[4] = { 0, 0, 0, 1 };
+
+      imm = tgsi_default_full_immediate();
+      imm.Immediate.NrTokens += 4;
+      imm.Immediate.DataType = TGSI_IMM_FLOAT32;
+      imm.u.Pointer = value;
+
+      ti += tgsi_build_full_immediate(&imm,
+                                      &tokens[ti],
+                                      header,
+                                      Elements(tokens) - ti );
+
+      /* MOV instruction */
+      inst = tgsi_default_full_instruction();
+      inst.Instruction.Opcode = TGSI_OPCODE_MOV;
+      inst.Instruction.NumDstRegs = 1;
+      inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
+      inst.FullDstRegisters[0].DstRegister.Index = 0;
+      inst.Instruction.NumSrcRegs = 1;
+      inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_IMMEDIATE;
+      inst.FullSrcRegisters[0].SrcRegister.Index = 0;
+      ti += tgsi_build_full_instruction(&inst,
+                                        &tokens[ti],
+                                        header,
+                                        Elements(tokens) - ti );
+   }
+
    /* TEX instruction */
    inst = tgsi_default_full_instruction();
    inst.Instruction.Opcode = TGSI_OPCODE_TEX;
    inst.Instruction.NumDstRegs = 1;
    inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
    inst.FullDstRegisters[0].DstRegister.Index = 0;
+   inst.FullDstRegisters[0].DstRegister.WriteMask = writemask;
    inst.Instruction.NumSrcRegs = 2;
    inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
    inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
@@ -253,6 +287,13 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
    return pipe->create_fs_state(pipe, &shader);
 }
 
+void *
+util_make_fragment_tex_shader(struct pipe_context *pipe )
+{
+   return util_make_fragment_tex_shader_writemask( pipe,
+                                                   TGSI_WRITEMASK_XYZW );
+}
+
 
 
 
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index 6f8d96a..d2e80d6 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -50,6 +50,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
 
 
 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);
 
 




More information about the mesa-commit mailing list