llvmpipe: Pass the alpha ref value and blend color in the jit context.
authorJosé Fonseca <jfonseca@vmware.com>
Sun, 23 Aug 2009 06:38:41 +0000 (07:38 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:41 +0000 (09:21 +0100)
src/gallium/drivers/llvmpipe/lp_bld_alpha.c
src/gallium/drivers/llvmpipe/lp_bld_alpha.h
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_jit.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_state_blend.c
src/gallium/drivers/llvmpipe/lp_state_fs.c

index 8d9af4cf6d91cdaead643fab6c2e357c5a9a2010..49c2f911af7be98ddb57a83cc9c75158997645b2 100644 (file)
@@ -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");
index 962ea9fafab8de6cc0433de05982b9ad3dc5567c..9dbcdb4daabe826f07384ff62ac2191444f92175 100644 (file)
@@ -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 */
index 8b4266b775c5c09999fe8b0b027968e4efdd04e2..8d5a0d4f1fc9c0a519ed86d4567fcc4801c570c8 100644 (file)
@@ -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;
index 92d5d43d0ccdba7c5d4aa2effc882f1771d525cb..0a32c41a6fa9cc2c55c5ece15b3b50090c11191e 100644 (file)
@@ -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);
 
index fe36b6092120122115eb4170a7a847832f07254f..e7e887fb64f76bc63c6415f071daa88b6ae0296c 100644 (file)
@@ -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,
index 34bcb9912d4a67885e5257bd465718dbaada98a9..d145f6d6bbc4f07737908d589f3e697bf5026b9a 100644 (file)
@@ -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,
index ebde41c09984de606078d0c5db4ced40430d7aae..3f03bd00571637d69b39230d9b53165155924703 100644 (file)
@@ -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;
 }
 
index 15dbfe8483c236ee227185baa97662fad0221210..eea332e3e48bdf50862ef84e6791a9452a3bb219 100644 (file)
@@ -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) {