llvmpipe: Separate pixel packing/unpacking from loading/storing.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 29 Jul 2009 06:58:27 +0000 (07:58 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:21 +0000 (09:21 +0100)
src/gallium/drivers/llvmpipe/Makefile
src/gallium/drivers/llvmpipe/SConscript
src/gallium/drivers/llvmpipe/lp_bld.h
src/gallium/drivers/llvmpipe/lp_bld_load.c [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_bld_pack.c
src/gallium/drivers/llvmpipe/lp_bld_store.c [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_bld_test.c
src/gallium/drivers/llvmpipe/lp_bld_unpack.c

index 20a8c44a24d16522f64fa3695110117645e44503..e06bf6668f6e264a663259ff82c6696981045062 100644 (file)
@@ -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 \
index c6c54d2f00dac4ae237eb8c35f925d657c5c8123..bba283f29680190f11fdd34d1dad4494218a7791 100644 (file)
@@ -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',
index 368182d6380ab0e195e3d79b4b1c12aa834c7090..44343f644ba8035be7324800c966837cc1a496dd 100644 (file)
 /**
  * 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 (file)
index 0000000..b9734bd
--- /dev/null
@@ -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);
+}
+
index 2383a07d725330d6e10a7464116a84bf0d2e2d5b..823d67e12db60d08fda8daccc5f3da96eb3658e7 100644 (file)
 #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 (file)
index 0000000..6273c9e
--- /dev/null
@@ -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);
+}
+
index 09947dd6bb67083218d740df2ff449a3cd4660f3..1f09310267192a85b3cddb7f001e1baea5b57913 100644 (file)
@@ -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);
 
    }
 
index cf6f8313282ada4f11c10d7d7d52dce37f0c6291..f1ffe3ecd8114747b95536cb901f5822c9a6d1f0 100644 (file)
 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), "");