Mesa (master): llvmpipe: Implement cylindrical wrapping.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Mon Jun 18 16:55:27 UTC 2012


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

Author: James Benton <jbenton at vmware.com>
Date:   Mon Jun 18 17:31:39 2012 +0100

llvmpipe: Implement cylindrical wrapping.

Tested against mesa demos cylwrap and dx9 DCT address.exe which now passes 100%.

Signed-off-by: José Fonseca <jfonseca at vmware.com>

---

 src/gallium/drivers/llvmpipe/lp_bld_interp.h  |    8 ++-
 src/gallium/drivers/llvmpipe/lp_state_fs.c    |    1 +
 src/gallium/drivers/llvmpipe/lp_state_setup.c |   77 ++++++++++++++++++++++++-
 3 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
index b0cbd9b..6970a9b 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
@@ -67,9 +67,11 @@ enum lp_interp {
 };
 
 struct lp_shader_input {
-   ushort interp:4;       /* enum lp_interp */
-   ushort usage_mask:4;   /* bitmask of TGSI_WRITEMASK_x flags */
-   ushort src_index:8;    /* where to find values in incoming vertices */
+   uint interp:4;       /* enum lp_interp */
+   uint usage_mask:4;   /* bitmask of TGSI_WRITEMASK_x flags */
+   uint src_index:8;    /* where to find values in incoming vertices */
+   uint cyl_wrap:4;     /* TGSI_CYLINDRICAL_WRAP_x flags */
+   uint padding:12;
 };
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 0bdc17f..7dd4969 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -1014,6 +1014,7 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
 
    for (i = 0; i < shader->info.base.num_inputs; i++) {
       shader->inputs[i].usage_mask = shader->info.base.input_usage_mask[i];
+      shader->inputs[i].cyl_wrap = shader->info.base.input_cylindrical_wrap[i];
 
       switch (shader->info.base.input_interpolate[i]) {
       case TGSI_INTERPOLATE_CONSTANT:
diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c
index 212bc1b..299c1ef 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c
@@ -34,6 +34,7 @@
 #include "gallivm/lp_bld_const.h"
 #include "gallivm/lp_bld_debug.h"
 #include "gallivm/lp_bld_init.h"
+#include "gallivm/lp_bld_logic.h"
 #include "gallivm/lp_bld_intr.h"
 #include "gallivm/lp_bld_flow.h"
 #include "gallivm/lp_bld_type.h"
@@ -454,6 +455,78 @@ emit_position_coef( struct gallivm_state *gallivm,
 }
 
 
+/**
+ * Applys cylindrical wrapping to vertex attributes if enabled.
+ * Input coordinates must be in [0, 1] range, otherwise results are undefined.
+ *
+ * @param cyl_wrap  TGSI_CYLINDRICAL_WRAP_x flags
+ */
+static void
+emit_apply_cyl_wrap(struct gallivm_state *gallivm,
+                    struct lp_setup_args *args,
+                    uint cyl_wrap)
+{
+   LLVMBuilderRef builder = gallivm->builder;
+   struct lp_type type = lp_float32_vec4_type();
+   LLVMTypeRef float_vec_type = lp_build_vec_type(gallivm, type);
+   LLVMValueRef pos_half;
+   LLVMValueRef neg_half;
+   LLVMValueRef cyl_mask;
+   LLVMValueRef offset;
+   LLVMValueRef delta;
+   LLVMValueRef one;
+
+   if (!cyl_wrap)
+      return;
+
+   /* Constants */
+   pos_half = lp_build_const_vec(gallivm, type, +0.5f);
+   neg_half = lp_build_const_vec(gallivm, type, -0.5f);
+   cyl_mask = lp_build_const_mask_aos(gallivm, type, cyl_wrap);
+
+   one = lp_build_const_vec(gallivm, type, 1.0f);
+   one = LLVMBuildBitCast(builder, one, lp_build_int_vec_type(gallivm, type), "");
+   one = LLVMBuildAnd(builder, one, cyl_mask, "");
+
+   /* Edge v0 -> v1 */
+   delta = LLVMBuildFSub(builder, args->v1a, args->v0a, "");
+
+   offset    = lp_build_compare(gallivm, type, PIPE_FUNC_GREATER, delta, pos_half);
+   offset    = LLVMBuildAnd(builder, offset, one, "");
+   offset    = LLVMBuildBitCast(builder, offset, float_vec_type, "");
+   args->v0a = LLVMBuildFAdd(builder, args->v0a, offset, "");
+
+   offset    = lp_build_compare(gallivm, type, PIPE_FUNC_LESS, delta, neg_half);
+   offset    = LLVMBuildAnd(builder, offset, one, "");
+   offset    = LLVMBuildBitCast(builder, offset, float_vec_type, "");
+   args->v1a = LLVMBuildFAdd(builder, args->v1a, offset, "");
+
+   /* Edge v1 -> v2 */
+   delta = LLVMBuildFSub(builder, args->v2a, args->v1a, "");
+
+   offset    = lp_build_compare(gallivm, type, PIPE_FUNC_GREATER, delta, pos_half);
+   offset    = LLVMBuildAnd(builder, offset, one, "");
+   offset    = LLVMBuildBitCast(builder, offset, float_vec_type, "");
+   args->v1a = LLVMBuildFAdd(builder, args->v1a, offset, "");
+
+   offset    = lp_build_compare(gallivm, type, PIPE_FUNC_LESS, delta, neg_half);
+   offset    = LLVMBuildAnd(builder, offset, one, "");
+   offset    = LLVMBuildBitCast(builder, offset, float_vec_type, "");
+   args->v2a = LLVMBuildFAdd(builder, args->v2a, offset, "");
+
+   /* Edge v2 -> v0 */
+   delta = LLVMBuildFSub(builder, args->v0a, args->v2a, "");
+
+   offset    = lp_build_compare(gallivm, type, PIPE_FUNC_GREATER, delta, pos_half);
+   offset    = LLVMBuildAnd(builder, offset, one, "");
+   offset    = LLVMBuildBitCast(builder, offset, float_vec_type, "");
+   args->v2a = LLVMBuildFAdd(builder, args->v2a, offset, "");
+
+   offset    = lp_build_compare(gallivm, type, PIPE_FUNC_LESS, delta, neg_half);
+   offset    = LLVMBuildAnd(builder, offset, one, "");
+   offset    = LLVMBuildBitCast(builder, offset, float_vec_type, "");
+   args->v0a = LLVMBuildFAdd(builder, args->v0a, offset, "");
+}
 
 
 /**
@@ -491,10 +564,12 @@ emit_tri_coef( struct gallivm_state *gallivm,
 	 break;
 
       case LP_INTERP_LINEAR:
+	 emit_apply_cyl_wrap(gallivm, args, key->inputs[slot].cyl_wrap);
 	 emit_linear_coef(gallivm, args, slot+1);
          break;
 
       case LP_INTERP_PERSPECTIVE:
+	 emit_apply_cyl_wrap(gallivm, args, key->inputs[slot].cyl_wrap);
 	 emit_perspective_coef(gallivm, args, slot+1);
          break;
 
@@ -763,7 +838,7 @@ lp_make_setup_variant_key(struct llvmpipe_context *lp,
    struct lp_fragment_shader *fs = lp->fs;
    unsigned i;
 
-   assert(sizeof key->inputs[0] == sizeof(ushort));
+   assert(sizeof key->inputs[0] == sizeof(uint));
    
    key->num_inputs = fs->info.base.num_inputs;
    key->flatshade_first = lp->rasterizer->flatshade_first;




More information about the mesa-commit mailing list