Mesa (master): gallium: Delay the creation of simple helper shaders

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Sat Mar 12 18:42:46 UTC 2011


Module: Mesa
Branch: master
Commit: 1a79064da12a8be71dca7656e5eebc4b85d2b35f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1a79064da12a8be71dca7656e5eebc4b85d2b35f

Author: Jakob Bornecrantz <wallbraker at gmail.com>
Date:   Sat Mar  5 13:27:00 2011 +0100

gallium: Delay the creation of simple helper shaders

---

 src/gallium/auxiliary/util/u_blit.c       |   92 +++++++++++++++++---------
 src/gallium/auxiliary/util/u_gen_mipmap.c |  104 +++++++++++++++-------------
 src/mesa/state_tracker/st_cb_clear.c      |   54 +++++++++++-----
 3 files changed, 154 insertions(+), 96 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index d1d7e86..421726b 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -128,21 +128,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
       ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
    }
 
-   /* vertex shader - still required to provide the linkage between
-    * fragment shader input semantics and vertex_element/buffers.
-    */
-   {
-      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
-                                      TGSI_SEMANTIC_GENERIC };
-      const uint semantic_indexes[] = { 0, 0 };
-      ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
-                                                    semantic_indexes);
-   }
-
-   /* fragment shader */
-   ctx->fs[TGSI_WRITEMASK_XYZW] =
-      util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
-                                    TGSI_INTERPOLATE_LINEAR);
    ctx->vbuf = NULL;
 
    /* init vertex data that doesn't change */
@@ -170,7 +155,8 @@ util_destroy_blit(struct blit_state *ctx)
    struct pipe_context *pipe = ctx->pipe;
    unsigned i;
 
-   pipe->delete_vs_state(pipe, ctx->vs);
+   if (ctx->vs)
+      pipe->delete_vs_state(pipe, ctx->vs);
 
    for (i = 0; i < Elements(ctx->fs); i++)
       if (ctx->fs[i])
@@ -186,6 +172,59 @@ util_destroy_blit(struct blit_state *ctx)
 
 
 /**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct blit_state *ctx, uint writemask)
+{
+   if (!ctx->fs[writemask])
+      ctx->fs[writemask] =
+         util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D,
+                                                 TGSI_INTERPOLATE_LINEAR,
+                                                 writemask);
+
+   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
+}
+
+
+/**
+ * Helper function to set the depthwrite shader.
+ */
+static INLINE void
+set_depth_fragment_shader(struct blit_state *ctx)
+{
+   if (!ctx->fs_depth)
+      ctx->fs_depth =
+         util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D,
+                                                  TGSI_INTERPOLATE_LINEAR);
+
+   cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct blit_state *ctx)
+{
+   /* vertex shader - still required to provide the linkage between
+    * fragment shader input semantics and vertex_element/buffers.
+    */
+   if (!ctx->vs) {
+      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+                                      TGSI_SEMANTIC_GENERIC };
+      const uint semantic_indexes[] = { 0, 0 };
+      ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+                                                    semantic_names,
+                                                    semantic_indexes);
+   }
+
+   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
+/**
  * Get offset of next free slot in vertex buffer for quad vertices.
  */
 static unsigned
@@ -530,22 +569,11 @@ util_blit_pixels_writemask(struct blit_state *ctx,
 
    /* shaders */
    if (dst_is_depth) {
-      if (ctx->fs_depth == NULL)
-         ctx->fs_depth =
-            util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D,
-                                                     TGSI_INTERPOLATE_LINEAR);
-
-      cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth);
+      set_depth_fragment_shader(ctx);
    } else {
-      if (ctx->fs[writemask] == NULL)
-         ctx->fs[writemask] =
-            util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
-                                                    TGSI_INTERPOLATE_LINEAR,
-                                                    writemask);
-
-      cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
+      set_fragment_shader(ctx, writemask);
    }
-   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+   set_vertex_shader(ctx);
 
    /* drawing dest */
    memset(&fb, 0, sizeof(fb));
@@ -720,8 +748,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
    cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view);
 
    /* shaders */
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
-   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+   set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW);
+   set_vertex_shader(ctx);
 
    /* drawing dest */
    memset(&fb, 0, sizeof(fb));
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 5bf0f53..4a16624 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -67,7 +67,7 @@ struct gen_mipmap_state
    struct pipe_vertex_element velem[2];
 
    void *vs;
-   void *fs1d, *fs2d, *fs3d, *fsCube, *fs1da, *fs2da;
+   void *fs[TGSI_TEXTURE_COUNT]; /**< Not all are used, but simplifies code */
 
    struct pipe_resource *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -1301,34 +1301,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
       ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
    }
 
-   /* vertex shader - still needed to specify mapping from fragment
-    * shader input semantics to vertex elements 
-    */
-   {
-      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
-                                      TGSI_SEMANTIC_GENERIC };
-      const uint semantic_indexes[] = { 0, 0 };
-      ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
-                                                    semantic_indexes);
-   }
-
-   /* fragment shader */
-   ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D,
-                                             TGSI_INTERPOLATE_LINEAR);
-   ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
-                                             TGSI_INTERPOLATE_LINEAR);
-   ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D,
-                                               TGSI_INTERPOLATE_LINEAR);
-   ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE,
-                                               TGSI_INTERPOLATE_LINEAR);
-   if (pipe->screen->get_param(pipe->screen, PIPE_CAP_ARRAY_TEXTURES)) {
-      ctx->fs1da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D_ARRAY,
-                                                 TGSI_INTERPOLATE_LINEAR);
-      ctx->fs2da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D_ARRAY,
-                                                 TGSI_INTERPOLATE_LINEAR);
-   }
-
-
    /* vertex data that doesn't change */
    for (i = 0; i < 4; i++) {
       ctx->vertices[i][0][2] = 0.0f; /* z */
@@ -1343,6 +1315,44 @@ util_create_gen_mipmap(struct pipe_context *pipe,
 
 
 /**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct gen_mipmap_state *ctx, uint type)
+{
+   if (!ctx->fs[type])
+      ctx->fs[type] =
+         util_make_fragment_tex_shader(ctx->pipe, type,
+                                       TGSI_INTERPOLATE_LINEAR);
+
+   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[type]);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct gen_mipmap_state *ctx)
+{
+   /* vertex shader - still required to provide the linkage between
+    * fragment shader input semantics and vertex_element/buffers.
+    */
+   if (!ctx->vs)
+   {
+      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+                                      TGSI_SEMANTIC_GENERIC };
+      const uint semantic_indexes[] = { 0, 0 };
+      ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+                                                    semantic_names,
+                                                    semantic_indexes);
+   }
+
+   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
+/**
  * Get next "slot" of vertex space in the vertex buffer.
  * We're allocating one large vertex buffer and using it piece by piece.
  */
@@ -1450,16 +1460,14 @@ void
 util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
+   unsigned i;
 
-   if (ctx->fs2da)
-      pipe->delete_fs_state(pipe, ctx->fs2da);
-   if (ctx->fs1da)
-      pipe->delete_fs_state(pipe, ctx->fs1da);
-   pipe->delete_fs_state(pipe, ctx->fsCube);
-   pipe->delete_fs_state(pipe, ctx->fs3d);
-   pipe->delete_fs_state(pipe, ctx->fs2d);
-   pipe->delete_fs_state(pipe, ctx->fs1d);
-   pipe->delete_vs_state(pipe, ctx->vs);
+   for (i = 0; i < Elements(ctx->fs); i++)
+      if (ctx->fs[i])
+         pipe->delete_fs_state(pipe, ctx->fs[i]);
+
+   if (ctx->vs)
+      pipe->delete_vs_state(pipe, ctx->vs);
 
    pipe_resource_reference(&ctx->vbuf, NULL);
 
@@ -1498,9 +1506,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    struct pipe_screen *screen = pipe->screen;
    struct pipe_framebuffer_state fb;
    struct pipe_resource *pt = psv->texture;
-   void *fs;
    uint dstLevel;
    uint offset;
+   uint type;
 
    /* The texture object should have room for the levels which we're
     * about to generate.
@@ -1515,26 +1523,26 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
 
    switch (pt->target) {
    case PIPE_TEXTURE_1D:
-      fs = ctx->fs1d;
+      type = TGSI_TEXTURE_1D;
       break;
    case PIPE_TEXTURE_2D:
-      fs = ctx->fs2d;
+      type = TGSI_TEXTURE_2D;
       break;
    case PIPE_TEXTURE_3D:
-      fs = ctx->fs3d;
+      type = TGSI_TEXTURE_3D;
       break;
    case PIPE_TEXTURE_CUBE:
-      fs = ctx->fsCube;
+      type = TGSI_TEXTURE_CUBE;
       break;
    case PIPE_TEXTURE_1D_ARRAY:
-      fs = ctx->fs1da;
+      type = TGSI_TEXTURE_1D_ARRAY;
       break;
    case PIPE_TEXTURE_2D_ARRAY:
-      fs = ctx->fs2da;
+      type = TGSI_TEXTURE_2D_ARRAY;
       break;
    default:
       assert(0);
-      fs = ctx->fs2d;
+      type = TGSI_TEXTURE_2D;
    }
 
    /* check if we can render in the texture's format */
@@ -1564,8 +1572,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_set_clip(ctx->cso, &ctx->clip);
    cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
 
-   cso_set_fragment_shader_handle(ctx->cso, fs);
-   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+   set_fragment_shader(ctx, type);
+   set_vertex_shader(ctx);
 
    /* init framebuffer state */
    memset(&fb, 0, sizeof(fb));
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 0e0c432..1eb748e 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -63,26 +63,12 @@
 void
 st_init_clear(struct st_context *st)
 {
-   struct pipe_context *pipe = st->pipe;
    struct pipe_screen *pscreen = st->pipe->screen;
 
    memset(&st->clear, 0, sizeof(st->clear));
 
    st->clear.raster.gl_rasterization_rules = 1;
    st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
-
-   /* fragment shader state: color pass-through program */
-   st->clear.fs = util_make_fragment_passthrough_shader(pipe);
-
-   /* vertex shader state: color/position pass-through */
-   {
-      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
-                                      TGSI_SEMANTIC_COLOR };
-      const uint semantic_indexes[] = { 0, 0 };
-      st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2,
-                                                         semantic_names,
-                                                         semantic_indexes);
-   }
 }
 
 
@@ -108,6 +94,42 @@ st_destroy_clear(struct st_context *st)
 
 
 /**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct st_context *st)
+{
+   if (!st->clear.fs)
+      st->clear.fs = util_make_fragment_passthrough_shader(st->pipe);
+
+   cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct st_context *st)
+{
+   /* vertex shader - still required to provide the linkage between
+    * fragment shader input semantics and vertex_element/buffers.
+    */
+   if (!st->clear.vs)
+   {
+      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+                                      TGSI_SEMANTIC_COLOR };
+      const uint semantic_indexes[] = { 0, 0 };
+      st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
+                                                         semantic_names,
+                                                         semantic_indexes);
+   }
+
+   cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
+}
+
+
+/**
  * Draw a screen-aligned quadrilateral.
  * Coords are clip coords with y=0=bottom.
  */
@@ -297,8 +319,8 @@ clear_with_quad(struct gl_context *ctx,
    }
 
    cso_set_clip(st->cso_context, &st->clear.clip);
-   cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
-   cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
+   set_fragment_shader(st);
+   set_vertex_shader(st);
 
    if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
       st_translate_color(ctx->Color.ClearColor,




More information about the mesa-commit mailing list