Mesa (master): llvmpipe: Relax the colormask constraint on opaque.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Sun Sep 5 09:18:04 UTC 2010


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

Author: José Fonseca <jfonseca at vmware.com>
Date:   Fri Sep  3 20:26:13 2010 +0100

llvmpipe: Relax the colormask constraint on opaque.

Also, include the color buffer in the key. Not having it there
causes a tight knots in the logic to determine when it is OK or not
to discard previous color buffer contents.

---

 src/gallium/drivers/llvmpipe/lp_state_fs.c |   37 +++++++++++++++++++---------
 src/gallium/drivers/llvmpipe/lp_state_fs.h |    5 +++-
 2 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 33c1a49..60cf98a 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -728,6 +728,9 @@ dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key)
 
    debug_printf("fs variant %p:\n", (void *) key);
 
+   for (i = 0; i < key->nr_cbufs; ++i) {
+      debug_printf("cbuf_format[%u] = %s\n", i, util_format_name(key->cbuf_format[i]));
+   }
    if (key->depth.enabled) {
       debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format));
       debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE));
@@ -798,6 +801,7 @@ generate_variant(struct llvmpipe_context *lp,
                  const struct lp_fragment_shader_variant_key *key)
 {
    struct lp_fragment_shader_variant *variant;
+   boolean fullcolormask;
 
    variant = CALLOC_STRUCT(lp_fragment_shader_variant);
    if(!variant)
@@ -820,11 +824,23 @@ generate_variant(struct llvmpipe_context *lp,
    generate_fragment(lp, shader, variant, RAST_WHOLE);
    generate_fragment(lp, shader, variant, RAST_EDGE_TEST);
 
-   /* TODO: most of these can be relaxed, in particular the colormask */
+   /*
+    * Determine whether we are touching all channels in the color buffer.
+    */
+   fullcolormask = FALSE;
+   if (key->nr_cbufs == 1) {
+      const struct util_format_description *format_desc;
+      format_desc = util_format_description(key->cbuf_format[0]);
+      if ((~key->blend.rt[0].colormask &
+           util_format_colormask(format_desc)) == 0) {
+         fullcolormask = TRUE;
+      }
+   }
+
    variant->opaque =
          !key->blend.logicop_enable &&
          !key->blend.rt[0].blend_enable &&
-         key->blend.rt[0].colormask == 0xf &&
+         fullcolormask &&
          !key->stencil[0].enabled &&
          !key->alpha.enabled &&
          !key->depth.enabled &&
@@ -1056,25 +1072,22 @@ make_variant_key(struct llvmpipe_context *lp,
 
    key->nr_cbufs = lp->framebuffer.nr_cbufs;
    for (i = 0; i < lp->framebuffer.nr_cbufs; i++) {
+      enum pipe_format format = lp->framebuffer.cbufs[i]->format;
       struct pipe_rt_blend_state *blend_rt = &key->blend.rt[i];
       const struct util_format_description *format_desc;
-      unsigned chan;
 
-      format_desc = util_format_description(lp->framebuffer.cbufs[i]->format);
+      key->cbuf_format[i] = format;
+
+      format_desc = util_format_description(format);
       assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
              format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
 
       blend_rt->colormask = lp->blend->rt[i].colormask;
 
-      /* mask out color channels not present in the color buffer.
-       * Should be simple to incorporate per-cbuf writemasks:
+      /*
+       * Mask out color channels not present in the color buffer.
        */
-      for(chan = 0; chan < 4; ++chan) {
-         enum util_format_swizzle swizzle = format_desc->swizzle[chan];
-
-         if(swizzle > UTIL_FORMAT_SWIZZLE_W)
-            blend_rt->colormask &= ~(1 << chan);
-      }
+      blend_rt->colormask &= util_format_colormask(format_desc);
 
       /*
        * Our swizzled render tiles always have an alpha channel, but the linear
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h
index 33c4800..f2c46a6 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.h
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h
@@ -51,12 +51,15 @@ struct lp_fragment_shader_variant_key
    struct pipe_stencil_state stencil[2];
    struct pipe_alpha_state alpha;
    struct pipe_blend_state blend;
-   enum pipe_format zsbuf_format;
+
    unsigned nr_cbufs:8;
    unsigned nr_samplers:8;	/* actually derivable from just the shader */
    unsigned flatshade:1;
    unsigned occlusion_count:1;
 
+   enum pipe_format zsbuf_format;
+   enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS];
+
    struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
 };
 




More information about the mesa-commit mailing list