Mesa (gallium-llvmpipe): llvmpipe: Separate pixel packing/ unpacking from loading/storing.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Wed Jul 29 07:29:18 UTC 2009


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

Author: José Fonseca <jfonseca at vmware.com>
Date:   Wed Jul 29 07:58:27 2009 +0100

llvmpipe: Separate pixel packing/unpacking from loading/storing.

---

 src/gallium/drivers/llvmpipe/Makefile        |    2 +
 src/gallium/drivers/llvmpipe/SConscript      |    2 +
 src/gallium/drivers/llvmpipe/lp_bld.h        |   34 +++++++++++++--
 src/gallium/drivers/llvmpipe/lp_bld_load.c   |   59 ++++++++++++++++++++++++++
 src/gallium/drivers/llvmpipe/lp_bld_pack.c   |   13 +++---
 src/gallium/drivers/llvmpipe/lp_bld_store.c  |   58 +++++++++++++++++++++++++
 src/gallium/drivers/llvmpipe/lp_bld_test.c   |   32 +++++++-------
 src/gallium/drivers/llvmpipe/lp_bld_unpack.c |   29 ++++++-------
 8 files changed, 185 insertions(+), 44 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 20a8c44..e06bf66 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -9,6 +9,8 @@ C_SOURCES = \
 	lp_fs_llvm.c \
 	lp_bld_pack.c \
 	lp_bld_unpack.c \
+	lp_bld_load.c \
+	lp_bld_store.c \
 	lp_bld_loop.c \
 	lp_clear.c \
 	lp_flush.c \
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index c6c54d2..bba283f 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -12,6 +12,8 @@ llvmpipe = env.ConvenienceLibrary(
 		'lp_fs_llvm.c',
 		'lp_bld_pack.c',
 		'lp_bld_unpack.c',
+		'lp_bld_load.c',
+		'lp_bld_store.c',
 		'lp_bld_loop.c',
 		'lp_clear.c',
 		'lp_context.c',
diff --git a/src/gallium/drivers/llvmpipe/lp_bld.h b/src/gallium/drivers/llvmpipe/lp_bld.h
index 368182d..44343f6 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld.h
@@ -48,15 +48,14 @@
 /**
  * Unpack a pixel into its RGBA components.
  *
- * @param ptr value with the pointer to the packed pixel. Pointer type is
- * irrelevant.
+ * @param packed integer.
  *
  * @return RGBA in a 4 floats vector.
  */
 LLVMValueRef
 lp_build_unpack_rgba(LLVMBuilderRef builder,
                      enum pipe_format format, 
-                     LLVMValueRef ptr);
+                     LLVMValueRef packed);
 
 
 /**
@@ -64,13 +63,38 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,
  *
  * @param rgba 4 float vector with the unpacked components.
  */
-void 
+LLVMValueRef
 lp_build_pack_rgba(LLVMBuilderRef builder,
                    enum pipe_format format,
-                   LLVMValueRef ptr,
                    LLVMValueRef rgba);
 
 
+/**
+ * Load a pixel into its RGBA components.
+ *
+ * @param ptr value with the pointer to the packed pixel. Pointer type is
+ * irrelevant.
+ *
+ * @return RGBA in a 4 floats vector.
+ */
+LLVMValueRef
+lp_build_load_rgba(LLVMBuilderRef builder,
+                   enum pipe_format format, 
+                   LLVMValueRef ptr);
+
+
+/**
+ * Store a pixel.
+ *
+ * @param rgba 4 float vector with the unpacked components.
+ */
+void 
+lp_build_store_rgba(LLVMBuilderRef builder,
+                    enum pipe_format format,
+                    LLVMValueRef ptr,
+                    LLVMValueRef rgba);
+
+
 struct lp_build_loop_state
 {
   LLVMBasicBlockRef block;
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_load.c b/src/gallium/drivers/llvmpipe/lp_bld_load.c
new file mode 100644
index 0000000..b9734bd
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_load.c
@@ -0,0 +1,59 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_format.h"
+
+#include "lp_bld.h"
+
+
+LLVMValueRef
+lp_build_load_rgba(LLVMBuilderRef builder,
+                   enum pipe_format format,
+                   LLVMValueRef ptr)
+{
+   const struct util_format_description *desc;
+   LLVMTypeRef type;
+   LLVMValueRef packed;
+
+   desc = util_format_description(format);
+
+   /* FIXME: Support more formats */
+   assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+   assert(desc->block.width == 1);
+   assert(desc->block.height == 1);
+   assert(desc->block.bits <= 32);
+
+   type = LLVMIntType(desc->block.bits);
+
+   ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
+
+   packed = LLVMBuildLoad(builder, ptr, "");
+
+   return lp_build_unpack_rgba(builder, format, packed);
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_pack.c b/src/gallium/drivers/llvmpipe/lp_bld_pack.c
index 2383a07..823d67e 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_pack.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_pack.c
@@ -31,10 +31,9 @@
 #include "lp_bld.h"
 
 
-void
+LLVMValueRef
 lp_build_pack_rgba(LLVMBuilderRef builder,
                    enum pipe_format format,
-                   LLVMValueRef ptr,
                    LLVMValueRef rgba)
 {
    const struct util_format_description *desc;
@@ -121,12 +120,12 @@ lp_build_pack_rgba(LLVMBuilderRef builder,
       }
    }
 
-   if (packed) {
+   if (!packed)
+      packed = LLVMGetUndef(LLVMInt32Type());
 
-      if (desc->block.bits < 32)
-         packed = LLVMBuildTrunc(builder, packed, type, "");
+   if (desc->block.bits < 32)
+      packed = LLVMBuildTrunc(builder, packed, type, "");
 
-      LLVMBuildStore(builder, packed, LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), ""));
-   }
+   return packed;
 }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_store.c b/src/gallium/drivers/llvmpipe/lp_bld_store.c
new file mode 100644
index 0000000..6273c9e
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_store.c
@@ -0,0 +1,58 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_format.h"
+
+#include "lp_bld.h"
+
+
+void
+lp_build_store_rgba(LLVMBuilderRef builder,
+                    enum pipe_format format,
+                    LLVMValueRef ptr,
+                    LLVMValueRef rgba)
+{
+   const struct util_format_description *desc;
+   LLVMTypeRef type;
+   LLVMValueRef packed;
+
+   desc = util_format_description(format);
+
+   assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+   assert(desc->block.width == 1);
+   assert(desc->block.height == 1);
+
+   type = LLVMIntType(desc->block.bits);
+
+   packed = lp_build_pack_rgba(builder, format, rgba);
+
+   ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
+
+   LLVMBuildStore(builder, packed, ptr);
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_test.c b/src/gallium/drivers/llvmpipe/lp_bld_test.c
index 09947dd..1f09310 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_test.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_test.c
@@ -89,14 +89,14 @@ struct pixel_test_case test_cases[] =
 
 
 static LLVMValueRef
-add_unpack_rgba_test(LLVMModuleRef module,
-                     enum pipe_format format)
+add_load_rgba_test(LLVMModuleRef module,
+                   enum pipe_format format)
 {
    LLVMTypeRef args[] = {
       LLVMPointerType(LLVMInt8Type(), 0),
       LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0)
    };
-   LLVMValueRef func = LLVMAddFunction(module, "unpack", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
+   LLVMValueRef func = LLVMAddFunction(module, "load", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
    LLVMValueRef ptr = LLVMGetParam(func, 0);
    LLVMValueRef rgba_ptr = LLVMGetParam(func, 1);
@@ -111,7 +111,7 @@ add_unpack_rgba_test(LLVMModuleRef module,
 
    lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), &loop);
 
-   rgba = lp_build_unpack_rgba(builder, format, ptr);
+   rgba = lp_build_load_rgba(builder, format, ptr);
    LLVMBuildStore(builder, rgba, rgba_ptr);
 
    lp_build_loop_end(builder, LLVMConstInt(LLVMInt32Type(), 4, 0), NULL, &loop);
@@ -124,14 +124,14 @@ add_unpack_rgba_test(LLVMModuleRef module,
 
 
 static LLVMValueRef
-add_pack_rgba_test(LLVMModuleRef module,
-                   enum pipe_format format)
+add_store_rgba_test(LLVMModuleRef module,
+                    enum pipe_format format)
 {
    LLVMTypeRef args[] = {
       LLVMPointerType(LLVMInt8Type(), 0),
       LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0)
    };
-   LLVMValueRef func = LLVMAddFunction(module, "pack", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
+   LLVMValueRef func = LLVMAddFunction(module, "store", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
    LLVMValueRef ptr = LLVMGetParam(func, 0);
    LLVMValueRef rgba_ptr = LLVMGetParam(func, 1);
@@ -144,7 +144,7 @@ add_pack_rgba_test(LLVMModuleRef module,
 
    rgba = LLVMBuildLoad(builder, rgba_ptr, "");
 
-   lp_build_pack_rgba(builder, format, ptr, rgba);
+   lp_build_store_rgba(builder, format, ptr, rgba);
 
    LLVMBuildRetVoid(builder);
 
@@ -164,8 +164,8 @@ test_format(const struct pixel_test_case *test)
 
    LLVMModuleRef module = LLVMModuleCreateWithName("test");
 
-   LLVMValueRef unpack = add_unpack_rgba_test(module, test->format);
-   LLVMValueRef pack = add_pack_rgba_test(module, test->format);
+   LLVMValueRef load = add_load_rgba_test(module, test->format);
+   LLVMValueRef store = add_store_rgba_test(module, test->format);
 
    LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
    LLVMDisposeMessage(error);
@@ -200,19 +200,19 @@ test_format(const struct pixel_test_case *test)
    unsigned packed = 0;
 
    {
-      typedef void (*unpack_ptr_t)(const void *, float *);
-      unpack_ptr_t unpack_ptr = (unpack_ptr_t)LLVMGetPointerToGlobal(engine, unpack);
+      typedef void (*load_ptr_t)(const void *, float *);
+      load_ptr_t load_ptr = (load_ptr_t)LLVMGetPointerToGlobal(engine, load);
 
-      unpack_ptr(&test->packed, unpacked);
+      load_ptr(&test->packed, unpacked);
 
    }
 
 
    {
-      typedef void (*pack_ptr_t)(void *, const float *);
-      pack_ptr_t pack_ptr = (pack_ptr_t)LLVMGetPointerToGlobal(engine, pack);
+      typedef void (*store_ptr_t)(void *, const float *);
+      store_ptr_t store_ptr = (store_ptr_t)LLVMGetPointerToGlobal(engine, store);
 
-      pack_ptr(&packed, unpacked);
+      store_ptr(&packed, unpacked);
 
    }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_unpack.c b/src/gallium/drivers/llvmpipe/lp_bld_unpack.c
index cf6f831..f1ffe3e 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_unpack.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_unpack.c
@@ -34,11 +34,10 @@
 LLVMValueRef
 lp_build_unpack_rgba(LLVMBuilderRef builder,
                      enum pipe_format format,
-                     LLVMValueRef ptr)
+                     LLVMValueRef packed)
 {
    const struct util_format_description *desc;
    LLVMTypeRef type;
-   LLVMValueRef deferred;
    unsigned shift = 0;
    unsigned i;
 
@@ -52,24 +51,22 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,
 
    type = LLVMIntType(desc->block.bits);
 
-   deferred = LLVMBuildLoad(builder, LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), ""), "");
-
    /* Do the intermediate integer computations with 32bit integers since it
     * matches floating point size */
    if (desc->block.bits < 32)
-      deferred = LLVMBuildZExt(builder, deferred, LLVMInt32Type(), "");
+      packed = LLVMBuildZExt(builder, packed, LLVMInt32Type(), "");
 
    /* Broadcast the packed value to all four channels */
-   deferred = LLVMBuildInsertElement(builder,
-                                     LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
-                                     deferred,
-                                     LLVMConstNull(LLVMInt32Type()),
-                                     "");
-   deferred = LLVMBuildShuffleVector(builder,
-                                     deferred,
-                                     LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
-                                     LLVMConstNull(LLVMVectorType(LLVMInt32Type(), 4)),
-                                     "");
+   packed = LLVMBuildInsertElement(builder,
+                                   LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
+                                   packed,
+                                   LLVMConstNull(LLVMInt32Type()),
+                                   "");
+   packed = LLVMBuildShuffleVector(builder,
+                                   packed,
+                                   LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
+                                   LLVMConstNull(LLVMVectorType(LLVMInt32Type(), 4)),
+                                   "");
 
    LLVMValueRef shifted, casted, scaled, masked, swizzled;
    LLVMValueRef shifts[4];
@@ -108,7 +105,7 @@ lp_build_unpack_rgba(LLVMBuilderRef builder,
       shift += bits;
    }
 
-   shifted = LLVMBuildLShr(builder, deferred, LLVMConstVector(shifts, 4), "");
+   shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), "");
    masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), "");
    // UIToFP can't be expressed in SSE2
    casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), "");




More information about the mesa-commit mailing list