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

Author: Adhemerval Zanella <[email protected]>
Date:   Sun Jan 20 11:42:16 2013 -0600

llvmpipe: fix vertex_header mask store in big-endian

This patch fixes the vertex_header mask bitfield store in big-endian
architectures by bit-swap the fields accordingly.

Reviewed-by: Adam Jackson <[email protected]>

---

 src/gallium/auxiliary/draw/draw_llvm.c |   48 ++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_llvm.c 
b/src/gallium/auxiliary/draw/draw_llvm.c
index dc83f80..f3bbbbb 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -646,6 +646,53 @@ store_aos(struct gallivm_state *gallivm,
    lp_set_store_alignment(LLVMBuildStore(builder, value, data_ptr), 
sizeof(float));
 }
 
+/**
+ * Adjust the mask to architecture endianess. The mask will the store in 
struct:
+ *
+ * struct vertex_header {
+ *    unsigned clipmask:DRAW_TOTAL_CLIP_PLANES;
+ *    unsigned edgeflag:1;
+ *    unsigned have_clipdist:1;
+ *    unsigned vertex_id:16;
+ *    [...]
+ * }
+ *
+ * On little-endian machine nothing needs to done, however on bit-endian 
machine
+ * the mask's fields need to be adjusted with the algorithm:
+ *
+ * uint32_t reverse (uint32_t x)
+ * {
+ *   return (x >> 16) |              // vertex_id
+ *          ((x & 0x3fff) << 18) |   // clipmask
+ *          ((x & 0x4000) << 3) |    // have_clipdist
+ *          ((x & 0x8000) << 1);     // edgeflag
+ * }
+ */
+static LLVMValueRef
+adjust_mask(struct gallivm_state *gallivm,
+            LLVMValueRef mask)
+{
+#ifdef PIPE_ARCH_BIG_ENDIAN
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef vertex_id;
+   LLVMValueRef clipmask;
+   LLVMValueRef have_clipdist;
+   LLVMValueRef edgeflag;
+
+   vertex_id = LLVMBuildLShr(builder, mask, lp_build_const_int32(gallivm, 16), 
"");
+   clipmask  = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 
0x3fff), "");
+   clipmask  = LLVMBuildShl(builder, clipmask, lp_build_const_int32(gallivm, 
18), "");
+   have_clipdist = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 
0x4000), "");
+   have_clipdist = LLVMBuildShl(builder, have_clipdist, 
lp_build_const_int32(gallivm, 3), "");
+   edgeflag = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 
0x8000), "");
+   edgeflag = LLVMBuildShl(builder, edgeflag, lp_build_const_int32(gallivm, 
1), "");
+
+   mask = LLVMBuildOr(builder, vertex_id, clipmask, "");
+   mask = LLVMBuildOr(builder, mask, have_clipdist, "");
+   mask = LLVMBuildOr(builder, mask, edgeflag, "");
+#endif
+   return mask;
+}
 
 static void
 store_aos_array(struct gallivm_state *gallivm,
@@ -690,6 +737,7 @@ store_aos_array(struct gallivm_state *gallivm,
       for (i = 0; i < vector_length; i++) {
          LLVMValueRef id_ptr = draw_jit_header_id(gallivm, io_ptrs[i]);
          val = LLVMBuildExtractElement(builder, cliptmp, inds[i], "");
+         val = adjust_mask(gallivm, val);
          LLVMBuildStore(builder, val, id_ptr);
 #if DEBUG_STORE
          lp_build_printf(gallivm, "io = %p, index %d\n, clipmask = %x\n",

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to