[Mesa-dev] [PATCH 02/22] gallium/u_gen_mipmap: accelerate depth texture mipmap generation

Marek Olšák maraeo at gmail.com
Mon Jul 9 12:15:35 PDT 2012


---
 src/gallium/auxiliary/util/u_gen_mipmap.c |   84 ++++++++++++++++++++---------
 1 file changed, 58 insertions(+), 26 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 2ff1af7..a96cf6a 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -59,14 +59,17 @@ struct gen_mipmap_state
    struct pipe_context *pipe;
    struct cso_context *cso;
 
-   struct pipe_blend_state blend;
-   struct pipe_depth_stencil_alpha_state depthstencil;
+   struct pipe_blend_state blend_keep_color, blend_write_color;
+   struct pipe_depth_stencil_alpha_state dsa_keep_depth, dsa_write_depth;
    struct pipe_rasterizer_state rasterizer;
    struct pipe_sampler_state sampler;
    struct pipe_vertex_element velem[2];
 
    void *vs;
-   void *fs[TGSI_TEXTURE_COUNT]; /**< Not all are used, but simplifies code */
+
+   /** Not all are used, but simplifies code */
+   void *fs_color[TGSI_TEXTURE_COUNT];
+   void *fs_depth[TGSI_TEXTURE_COUNT];
 
    struct pipe_resource *vbuf;  /**< quad vertices */
    unsigned vbuf_slot;
@@ -1272,11 +1275,16 @@ util_create_gen_mipmap(struct pipe_context *pipe,
    ctx->cso = cso;
 
    /* disabled blending/masking */
-   memset(&ctx->blend, 0, sizeof(ctx->blend));
-   ctx->blend.rt[0].colormask = PIPE_MASK_RGBA;
+   memset(&ctx->blend_keep_color, 0, sizeof(ctx->blend_keep_color));
+   memset(&ctx->blend_write_color, 0, sizeof(ctx->blend_write_color));
+   ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA;
 
    /* no-op depth/stencil/alpha */
-   memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
+   memset(&ctx->dsa_keep_depth, 0, sizeof(ctx->dsa_keep_depth));
+   memset(&ctx->dsa_write_depth, 0, sizeof(ctx->dsa_write_depth));
+   ctx->dsa_write_depth.depth.enabled = 1;
+   ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS;
+   ctx->dsa_write_depth.depth.writemask = 1;
 
    /* rasterizer */
    memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
@@ -1318,14 +1326,25 @@ 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)
+set_fragment_shader(struct gen_mipmap_state *ctx, uint type,
+                    boolean output_depth)
 {
-   if (!ctx->fs[type])
-      ctx->fs[type] =
-         util_make_fragment_tex_shader(ctx->pipe, type,
-                                       TGSI_INTERPOLATE_LINEAR);
+   if (output_depth) {
+      if (!ctx->fs_depth[type])
+         ctx->fs_depth[type] =
+            util_make_fragment_tex_shader_writedepth(ctx->pipe, type,
+                                                     TGSI_INTERPOLATE_LINEAR);
 
-   cso_set_fragment_shader_handle(ctx->cso, ctx->fs[type]);
+      cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[type]);
+   }
+   else {
+      if (!ctx->fs_color[type])
+         ctx->fs_color[type] =
+            util_make_fragment_tex_shader(ctx->pipe, type,
+                                          TGSI_INTERPOLATE_LINEAR);
+
+      cso_set_fragment_shader_handle(ctx->cso, ctx->fs_color[type]);
+   }
 }
 
 
@@ -1464,9 +1483,13 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
    struct pipe_context *pipe = ctx->pipe;
    unsigned i;
 
-   for (i = 0; i < Elements(ctx->fs); i++)
-      if (ctx->fs[i])
-         pipe->delete_fs_state(pipe, ctx->fs[i]);
+   for (i = 0; i < Elements(ctx->fs_color); i++)
+      if (ctx->fs_color[i])
+         pipe->delete_fs_state(pipe, ctx->fs_color[i]);
+
+   for (i = 0; i < Elements(ctx->fs_depth); i++)
+      if (ctx->fs_depth[i])
+         pipe->delete_fs_state(pipe, ctx->fs_depth[i]);
 
    if (ctx->vs)
       pipe->delete_vs_state(pipe, ctx->vs);
@@ -1500,6 +1523,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    uint dstLevel;
    uint offset;
    uint type;
+   boolean is_depth = util_format_is_depth_or_stencil(psv->format);
 
    /* The texture object should have room for the levels which we're
     * about to generate.
@@ -1538,7 +1562,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
 
    /* check if we can render in the texture's format */
    if (!screen->is_format_supported(screen, psv->format, pt->target,
-                                    pt->nr_samples, PIPE_BIND_RENDER_TARGET)) {
+                                    pt->nr_samples,
+                                    is_depth ? PIPE_BIND_DEPTH_STENCIL :
+                                               PIPE_BIND_RENDER_TARGET)) {
       fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
       return;
    }
@@ -1559,28 +1585,25 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_save_vertex_buffers(ctx->cso);
 
    /* bind our state */
-   cso_set_blend(ctx->cso, &ctx->blend);
-   cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
+   cso_set_blend(ctx->cso, is_depth ? &ctx->blend_keep_color :
+                                      &ctx->blend_write_color);
+   cso_set_depth_stencil_alpha(ctx->cso, is_depth ? &ctx->dsa_write_depth :
+                                                    &ctx->dsa_keep_depth);
    cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
    cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
    cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
 
-   set_fragment_shader(ctx, type);
+   set_fragment_shader(ctx, type, is_depth);
    set_vertex_shader(ctx);
    cso_set_geometry_shader_handle(ctx->cso, NULL);
 
    /* init framebuffer state */
    memset(&fb, 0, sizeof(fb));
-   fb.nr_cbufs = 1;
 
    /* set min/mag to same filter for faster sw speed */
    ctx->sampler.mag_img_filter = filter;
    ctx->sampler.min_img_filter = filter;
 
-   /*
-    * XXX for small mipmap levels, it may be faster to use the software
-    * fallback path...
-    */
    for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
       const uint srcLevel = dstLevel - 1;
       struct pipe_viewport_state vp;
@@ -1609,7 +1632,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
             layer = face;
 
          memset(&surf_templ, 0, sizeof(surf_templ));
-         u_surface_default_template(&surf_templ, pt, PIPE_BIND_RENDER_TARGET);
+         u_surface_default_template(&surf_templ, pt,
+                                    is_depth ? PIPE_BIND_DEPTH_STENCIL :
+                                               PIPE_BIND_RENDER_TARGET);
          surf_templ.u.tex.level = dstLevel;
          surf_templ.u.tex.first_layer = layer;
          surf_templ.u.tex.last_layer = layer;
@@ -1618,7 +1643,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
          /*
           * Setup framebuffer / dest surface
           */
-         fb.cbufs[0] = surf;
+         if (is_depth) {
+            fb.nr_cbufs = 0;
+            fb.zsbuf = surf;
+         }
+         else {
+            fb.nr_cbufs = 1;
+            fb.cbufs[0] = surf;
+         }
          fb.width = u_minify(pt->width0, dstLevel);
          fb.height = u_minify(pt->height0, dstLevel);
          cso_set_framebuffer(ctx->cso, &fb);
-- 
1.7.9.5



More information about the mesa-dev mailing list