Mesa (gallium-llvmpipe): llvmpipe: Pass the alpha ref value and blend color in the jit context.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Sun Aug 23 11:29:26 UTC 2009


Module: Mesa
Branch: gallium-llvmpipe
Commit: 89c261d64e8dee390ed599100e87e6227e0e6e84
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=89c261d64e8dee390ed599100e87e6227e0e6e84

Author: José Fonseca <jfonseca at vmware.com>
Date:   Sun Aug 23 07:38:41 2009 +0100

llvmpipe: Pass the alpha ref value and blend color in the jit context.

---

 src/gallium/drivers/llvmpipe/lp_bld_alpha.c   |    4 +-
 src/gallium/drivers/llvmpipe/lp_bld_alpha.h   |    3 +-
 src/gallium/drivers/llvmpipe/lp_context.h     |    2 +-
 src/gallium/drivers/llvmpipe/lp_jit.c         |    8 ++-
 src/gallium/drivers/llvmpipe/lp_jit.h         |    9 +++
 src/gallium/drivers/llvmpipe/lp_setup.c       |    2 +-
 src/gallium/drivers/llvmpipe/lp_state_blend.c |   15 +++-
 src/gallium/drivers/llvmpipe/lp_state_fs.c    |   93 ++++++++++++++-----------
 8 files changed, 86 insertions(+), 50 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
index 8d9af4c..49c2f91 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
@@ -47,14 +47,14 @@ lp_build_alpha_test(LLVMBuilderRef builder,
                     const struct pipe_alpha_state *state,
                     union lp_type type,
                     struct lp_build_mask_context *mask,
-                    LLVMValueRef alpha)
+                    LLVMValueRef alpha,
+                    LLVMValueRef ref)
 {
    struct lp_build_context bld;
 
    lp_build_context_init(&bld, builder, type);
 
    if(state->enabled) {
-      LLVMValueRef ref = lp_build_const_scalar(type, state->ref_value);
       LLVMValueRef test = lp_build_cmp(&bld, state->func, alpha, ref);
 
       lp_build_name(test, "alpha_mask");
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
index 962ea9f..9dbcdb4 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
@@ -47,7 +47,8 @@ lp_build_alpha_test(LLVMBuilderRef builder,
                     const struct pipe_alpha_state *state,
                     union lp_type type,
                     struct lp_build_mask_context *mask,
-                    LLVMValueRef alpha);
+                    LLVMValueRef alpha,
+                    LLVMValueRef ref);
 
 
 #endif /* !LP_BLD_ALPHA_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 8b4266b..8d5a0d4 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -61,7 +61,7 @@ struct llvmpipe_context {
    const struct lp_vertex_shader *vs;
 
    /** Other rendering state */
-   uint8_t ALIGN16_ATTRIB blend_color[4][16];
+   struct pipe_blend_color blend_color[4][16];
    struct pipe_clip_state clip;
    struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
    struct pipe_framebuffer_state framebuffer;
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 92d5d43..0a32c41 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -45,11 +45,13 @@ lp_jit_init_types(struct llvmpipe_screen *screen)
 {
    /* struct lp_jit_context */
    {
-      LLVMTypeRef elem_types[2];
+      LLVMTypeRef elem_types[4];
       LLVMTypeRef context_type;
 
       elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
       elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0);  /* samplers */
+      elem_types[2] = LLVMFloatType();                     /* alpha_ref_value */
+      elem_types[3] = LLVMPointerType(LLVMInt8Type(), 0);  /* blend_color */
 
       context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
 
@@ -57,6 +59,10 @@ lp_jit_init_types(struct llvmpipe_screen *screen)
                              screen->target, context_type, 0);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers,
                              screen->target, context_type, 1);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
+                             screen->target, context_type, 2);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
+                             screen->target, context_type, 3);
       LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
                            screen->target, context_type);
 
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index fe36b60..e7e887f 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -61,7 +61,10 @@ struct lp_jit_context
    struct tgsi_sampler **samplers;
 
    /* TODO: alpha reference value */
+   float alpha_ref_value;
+
    /* TODO: blend constant color */
+   uint8_t *blend_color;
 };
 
 
@@ -71,6 +74,12 @@ struct lp_jit_context
 #define lp_jit_context_samplers(_builder, _ptr) \
    lp_build_struct_get(_builder, _ptr, 1, "context.samplers")
 
+#define lp_jit_context_alpha_ref_value(_builder, _ptr) \
+   lp_build_struct_get(_builder, _ptr, 2, "context.alpha")
+
+#define lp_jit_context_blend_color(_builder, _ptr) \
+   lp_build_struct_get(_builder, _ptr, 3, "context.blend")
+
 
 typedef void
 (*lp_jit_frag_func)(struct lp_jit_context *context,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 34bcb99..d145f6d 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -167,7 +167,7 @@ shade_quads(struct llvmpipe_context *llvmpipe,
    assert((((uintptr_t)mask) & 0xf) == 0);
    assert((((uintptr_t)depth) & 0xf) == 0);
    assert((((uintptr_t)color) & 0xf) == 0);
-   assert((((uintptr_t)llvmpipe->blend_color) & 0xf) == 0);
+   assert((((uintptr_t)llvmpipe->jit_context.blend_color) & 0xf) == 0);
 
    /* run shader */
    fs->current->jit_function( &llvmpipe->jit_context,
diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c
index ebde41c..3f03bd0 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c
@@ -69,11 +69,15 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe,
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    unsigned i, j;
 
-   for (i = 0; i < 4; ++i)
-      for (j = 0; j < 16; ++j)
-         llvmpipe->blend_color[i][j] = float_to_ubyte(blend_color->color[i]);
+   memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color);
 
-   llvmpipe->dirty |= LP_NEW_BLEND;
+   if(!llvmpipe->jit_context.blend_color)
+      llvmpipe->jit_context.blend_color = align_malloc(4 * 16, 16);
+   for (i = 0; i < 4; ++i) {
+      uint8_t c = float_to_ubyte(blend_color->color[i]);
+      for (j = 0; j < 16; ++j)
+         llvmpipe->jit_context.blend_color[i*4 + j] = c;
+   }
 }
 
 
@@ -97,6 +101,9 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
 
    llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
 
+   if(llvmpipe->depth_stencil)
+      llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value;
+
    llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA;
 }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 15dbfe8..eea332e 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -216,22 +216,23 @@ generate_fs(struct llvmpipe_context *lp,
             const struct lp_fragment_shader_variant_key *key,
             LLVMBuilderRef builder,
             union lp_type type,
+            LLVMValueRef context_ptr,
             unsigned i,
             LLVMValueRef x,
             LLVMValueRef y,
             LLVMValueRef a0_ptr,
             LLVMValueRef dadx_ptr,
             LLVMValueRef dady_ptr,
-            LLVMValueRef consts_ptr,
             LLVMValueRef *pmask,
             LLVMValueRef *color,
-            LLVMValueRef depth_ptr,
-            LLVMValueRef samplers_ptr)
+            LLVMValueRef depth_ptr)
 {
    const struct tgsi_token *tokens = shader->base.tokens;
    LLVMTypeRef elem_type;
    LLVMTypeRef vec_type;
    LLVMTypeRef int_vec_type;
+   LLVMValueRef consts_ptr;
+   LLVMValueRef samplers_ptr;
    LLVMValueRef pos[NUM_CHANNELS];
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
    struct lp_build_mask_context mask;
@@ -243,6 +244,9 @@ generate_fs(struct llvmpipe_context *lp,
    vec_type = lp_build_vec_type(type);
    int_vec_type = lp_build_int_vec_type(type);
 
+   consts_ptr = lp_jit_context_constants(builder, context_ptr);
+   samplers_ptr = lp_jit_context_samplers(builder, context_ptr);
+
    generate_pos(builder, x, y, a0_ptr, dadx_ptr, dady_ptr, pos);
 
    lp_build_mask_begin(&mask, builder, type, *pmask);
@@ -279,10 +283,14 @@ generate_fs(struct llvmpipe_context *lp,
 
                   /* Alpha test */
                   /* XXX: should the alpha reference value be passed separately? */
-                  if(cbuf == 0 && chan == 3)
+                  if(cbuf == 0 && chan == 3) {
+                     LLVMValueRef alpha = outputs[attrib][chan];
+                     LLVMValueRef alpha_ref_value;
+                     alpha_ref_value = lp_jit_context_alpha_ref_value(builder, context_ptr);
+                     alpha_ref_value = lp_build_broadcast(builder, vec_type, alpha_ref_value);
                      lp_build_alpha_test(builder, &key->alpha, type,
-                                         &mask,
-                                         outputs[attrib][chan]);
+                                         &mask, alpha, alpha_ref_value);
+                  }
 
                   if(cbuf == 0)
                      color[chan] = outputs[attrib][chan];
@@ -318,14 +326,15 @@ static void
 generate_blend(const struct pipe_blend_state *blend,
                LLVMBuilderRef builder,
                union lp_type type,
+               LLVMValueRef context_ptr,
                LLVMValueRef mask,
                LLVMValueRef *src,
-               LLVMValueRef const_ptr,
                LLVMValueRef dst_ptr)
 {
    struct lp_build_context bld;
    LLVMTypeRef vec_type;
    LLVMTypeRef int_vec_type;
+   LLVMValueRef const_ptr;
    LLVMValueRef con[4];
    LLVMValueRef dst[4];
    LLVMValueRef res[4];
@@ -336,13 +345,13 @@ generate_blend(const struct pipe_blend_state *blend,
 
    lp_build_context_init(&bld, builder, type);
 
+   const_ptr = lp_jit_context_blend_color(builder, context_ptr);
+   const_ptr = LLVMBuildBitCast(builder, const_ptr,
+                                LLVMPointerType(vec_type, 0), "");
+
    for(chan = 0; chan < 4; ++chan) {
       LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
-
-      if(const_ptr)
-         con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
-      else
-         con[chan] = LLVMGetUndef(vec_type); /* FIXME */
+      con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
 
       dst[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
 
@@ -386,11 +395,9 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMValueRef a0_ptr;
    LLVMValueRef dadx_ptr;
    LLVMValueRef dady_ptr;
-   LLVMValueRef consts_ptr;
    LLVMValueRef mask_ptr;
    LLVMValueRef color_ptr;
    LLVMValueRef depth_ptr;
-   LLVMValueRef samplers_ptr;
    LLVMBasicBlockRef block;
    LLVMBuilderRef builder;
    LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
@@ -510,9 +517,6 @@ generate_fragment(struct llvmpipe_context *lp,
    builder = LLVMCreateBuilder();
    LLVMPositionBuilderAtEnd(builder, block);
 
-   consts_ptr = lp_jit_context_constants(builder, context_ptr);
-   samplers_ptr = lp_jit_context_samplers(builder, context_ptr);
-
    for(i = 0; i < num_fs; ++i) {
       LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
       LLVMValueRef out_color[NUM_CHANNELS];
@@ -525,22 +529,16 @@ generate_fragment(struct llvmpipe_context *lp,
       fs_mask[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, mask_ptr, &index, 1, ""), "");
       depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, "");
 
-      generate_fs(lp,
-                  shader,
-                  key,
+      generate_fs(lp, shader, key,
                   builder,
                   fs_type,
+                  context_ptr,
                   i,
-                  x_i,
-                  y,
-                  a0_ptr,
-                  dadx_ptr,
-                  dady_ptr,
-                  consts_ptr,
+                  x_i, y,
+                  a0_ptr, dadx_ptr, dady_ptr,
                   &fs_mask[i],
                   out_color,
-                  depth_ptr_i,
-                  samplers_ptr);
+                  depth_ptr_i);
 
       for(chan = 0; chan < NUM_CHANNELS; ++chan)
          fs_out_color[chan][i] = out_color[chan];
@@ -555,6 +553,7 @@ generate_fragment(struct llvmpipe_context *lp,
                     fs_out_color[chan], num_fs,
                     &blend_in_color[chan], 1);
       lp_build_name(blend_in_color[chan], "color.%c", "rgba"[chan]);
+
    }
 
    lp_build_conv_mask(builder, fs_type, blend_type,
@@ -568,9 +567,9 @@ generate_fragment(struct llvmpipe_context *lp,
    generate_blend(&key->blend,
                   builder,
                   blend_type,
+                  context_ptr,
                   blend_mask,
                   blend_in_color,
-                  NULL /* FIXME: blend_const_color */,
                   color_ptr);
 
    LLVMBuildRetVoid(builder);
@@ -698,6 +697,30 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
 }
 
 
+/**
+ * We need to generate several variants of the fragment pipeline to match
+ * all the combinations of the contributing state atoms.
+ *
+ * TODO: there is actually no reason to tie this to context state -- the
+ * generated code could be cached globally in the screen.
+ */
+static void
+make_variant_key(struct llvmpipe_context *lp,
+                 struct lp_fragment_shader_variant_key *key)
+{
+   memset(key, 0, sizeof *key);
+
+   memcpy(&key->depth, &lp->depth_stencil->depth, sizeof &key->depth);
+
+   key->alpha.enabled = lp->depth_stencil->alpha.enabled;
+   if(key->alpha.enabled)
+      key->alpha.func = lp->depth_stencil->alpha.func;
+   /* alpha.ref_value is passed in jit_context */
+
+   memcpy(&key->blend, lp->blend, sizeof &key->blend);
+}
+
+
 void 
 llvmpipe_update_fs(struct llvmpipe_context *lp)
 {
@@ -705,17 +728,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
    struct lp_fragment_shader_variant_key key;
    struct lp_fragment_shader_variant *variant;
 
-   /* We need to generate several variants of the fragment pipeline to match
-    * all the combinations of the contributing state atoms.
-    *
-    * TODO: there is actually no reason to tie this to context state -- the
-    * generated code could be cached globally in the screen.
-    */
-
-   memset(&key, 0, sizeof key);
-   memcpy(&key.depth, &lp->depth_stencil->depth, sizeof &key.depth);
-   memcpy(&key.alpha, &lp->depth_stencil->alpha, sizeof &key.alpha);
-   memcpy(&key.blend, lp->blend, sizeof &key.blend);
+   make_variant_key(lp, &key);
 
    variant = shader->variants;
    while(variant) {




More information about the mesa-commit mailing list