gallivm: Factor out the quad derivative code into a single place. Fix ddy.
authorJosé Fonseca <jfonseca@vmware.com>
Thu, 3 Jun 2010 13:16:59 +0000 (14:16 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Thu, 3 Jun 2010 13:32:56 +0000 (14:32 +0100)
For ddy it should be (bottom - top).

src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/auxiliary/gallivm/lp_bld_quad.c [new file with mode: 0644]
src/gallium/auxiliary/gallivm/lp_bld_quad.h [new file with mode: 0644]
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c

index 1abf12e95bdcb19aabe5f650fe444a6341b0695a..3b202b5bc774889abae6cd34320d71f225a8400a 100644 (file)
@@ -158,6 +158,7 @@ GALLIVM_SOURCES = \
         gallivm/lp_bld_logic.c \
         gallivm/lp_bld_pack.c \
         gallivm/lp_bld_printf.c \
+        gallivm/lp_bld_quad.c \
         gallivm/lp_bld_sample.c \
         gallivm/lp_bld_sample_soa.c \
         gallivm/lp_bld_struct.c \
index 7039d5f0c55ff083c655a7b666263507661199b1..af4d5edcf86866e38a154632d2cb3a2b6823f94f 100644 (file)
@@ -208,6 +208,7 @@ if env['llvm']:
     'gallivm/lp_bld_misc.cpp',
     'gallivm/lp_bld_pack.c',
     'gallivm/lp_bld_printf.c',
+    'gallivm/lp_bld_quad.c',
     'gallivm/lp_bld_sample.c',
     'gallivm/lp_bld_sample_soa.c',
     'gallivm/lp_bld_struct.c',
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_quad.c b/src/gallium/auxiliary/gallivm/lp_bld_quad.c
new file mode 100644 (file)
index 0000000..38fd5a3
--- /dev/null
@@ -0,0 +1,101 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#include "lp_bld_type.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_quad.h"
+
+
+static const unsigned char
+swizzle_left[4] = {
+   LP_BLD_QUAD_TOP_LEFT,     LP_BLD_QUAD_TOP_LEFT,
+   LP_BLD_QUAD_BOTTOM_LEFT,  LP_BLD_QUAD_BOTTOM_LEFT
+};
+
+static const unsigned char
+swizzle_right[4] = {
+   LP_BLD_QUAD_TOP_RIGHT,    LP_BLD_QUAD_TOP_RIGHT,
+   LP_BLD_QUAD_BOTTOM_RIGHT, LP_BLD_QUAD_BOTTOM_RIGHT
+};
+
+static const unsigned char
+swizzle_top[4] = {
+   LP_BLD_QUAD_TOP_LEFT,     LP_BLD_QUAD_TOP_RIGHT,
+   LP_BLD_QUAD_TOP_LEFT,     LP_BLD_QUAD_TOP_RIGHT
+};
+
+static const unsigned char
+swizzle_bottom[4] = {
+   LP_BLD_QUAD_BOTTOM_LEFT,  LP_BLD_QUAD_BOTTOM_RIGHT,
+   LP_BLD_QUAD_BOTTOM_LEFT,  LP_BLD_QUAD_BOTTOM_RIGHT
+};
+
+
+LLVMValueRef
+lp_build_ddx(struct lp_build_context *bld,
+             LLVMValueRef a)
+{
+   LLVMValueRef a_left  = lp_build_swizzle1_aos(bld, a, swizzle_left);
+   LLVMValueRef a_right = lp_build_swizzle1_aos(bld, a, swizzle_right);
+   return lp_build_sub(bld, a_right, a_left);
+}
+
+
+LLVMValueRef
+lp_build_ddy(struct lp_build_context *bld,
+             LLVMValueRef a)
+{
+   LLVMValueRef a_top    = lp_build_swizzle1_aos(bld, a, swizzle_top);
+   LLVMValueRef a_bottom = lp_build_swizzle1_aos(bld, a, swizzle_bottom);
+   return lp_build_sub(bld, a_bottom, a_top);
+}
+
+
+LLVMValueRef
+lp_build_scalar_ddx(struct lp_build_context *bld,
+                    LLVMValueRef a)
+{
+   LLVMValueRef idx_left  = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_TOP_LEFT, 0);
+   LLVMValueRef idx_right = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_TOP_RIGHT, 0);
+   LLVMValueRef a_left  = LLVMBuildExtractElement(bld->builder, a, idx_left, "");
+   LLVMValueRef a_right = LLVMBuildExtractElement(bld->builder, a, idx_right, "");
+   return LLVMBuildSub(bld->builder, a_right, a_left, "");
+}
+
+
+LLVMValueRef
+lp_build_scalar_ddy(struct lp_build_context *bld,
+                    LLVMValueRef a)
+{
+   LLVMValueRef idx_top    = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_TOP_LEFT, 0);
+   LLVMValueRef idx_bottom = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_BOTTOM_LEFT, 0);
+   LLVMValueRef a_top    = LLVMBuildExtractElement(bld->builder, a, idx_top, "");
+   LLVMValueRef a_bottom = LLVMBuildExtractElement(bld->builder, a, idx_bottom, "");
+   return LLVMBuildSub(bld->builder, a_bottom, a_top, "");
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_quad.h b/src/gallium/auxiliary/gallivm/lp_bld_quad.h
new file mode 100644 (file)
index 0000000..b799291
--- /dev/null
@@ -0,0 +1,96 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef LP_BLD_QUAD_H_
+#define LP_BLD_QUAD_H_
+
+
+#include "gallivm/lp_bld.h"
+
+
+struct lp_build_context;
+
+
+/*
+ * Each quad is composed of four elements.
+ *
+ * #########
+ * # 0 | 1 #
+ * #---+---#
+ * # 2 | 3 #
+ * #########
+ */
+
+enum lp_bld_quad {
+   LP_BLD_QUAD_TOP_LEFT     = 0,
+   LP_BLD_QUAD_TOP_RIGHT    = 1,
+   LP_BLD_QUAD_BOTTOM_LEFT  = 2,
+   LP_BLD_QUAD_BOTTOM_RIGHT = 3
+};
+
+
+/*
+ * (Vector) derivates.
+ *
+ * More than one quad is supported. The only requirement is that the vector
+ * contains a whole number of quads:
+ *
+ * ######### ######### ...
+ * # 0 | 1 # # 4 | 5 #
+ * #---+---# #---+---# ...
+ * # 2 | 3 # # 6 | 7 #
+ * ######### ######### ...
+ */
+
+LLVMValueRef
+lp_build_ddx(struct lp_build_context *bld,
+             LLVMValueRef a);
+
+
+LLVMValueRef
+lp_build_ddy(struct lp_build_context *bld,
+             LLVMValueRef a);
+
+
+/*
+ * Scalar derivatives.
+ *
+ * Same as getting the first value of above.
+ */
+
+LLVMValueRef
+lp_build_scalar_ddx(struct lp_build_context *bld,
+                    LLVMValueRef a);
+
+
+LLVMValueRef
+lp_build_scalar_ddy(struct lp_build_context *bld,
+                    LLVMValueRef a);
+
+
+#endif /* LP_BLD_QUAD_H_ */
index 40ea94c493537f4838c94d0f80eefd8ec68fcf69..ea949a136314a8289b1bf956e3df17d22c4ac5fa 100644 (file)
@@ -53,6 +53,7 @@
 #include "lp_bld_logic.h"
 #include "lp_bld_swizzle.h"
 #include "lp_bld_flow.h"
+#include "lp_bld_quad.h"
 #include "lp_bld_tgsi.h"
 #include "lp_bld_limits.h"
 #include "lp_bld_debug.h"
 #define CHAN_Z 2
 #define CHAN_W 3
 
-#define QUAD_TOP_LEFT     0
-#define QUAD_TOP_RIGHT    1
-#define QUAD_BOTTOM_LEFT  2
-#define QUAD_BOTTOM_RIGHT 3
-
 #define LP_MAX_INSTRUCTIONS 256
 
 
@@ -148,30 +144,6 @@ struct lp_build_tgsi_soa_context
    uint max_instructions;
 };
 
-static const unsigned char
-swizzle_left[4] = {
-   QUAD_TOP_LEFT,     QUAD_TOP_LEFT,
-   QUAD_BOTTOM_LEFT,  QUAD_BOTTOM_LEFT
-};
-
-static const unsigned char
-swizzle_right[4] = {
-   QUAD_TOP_RIGHT,    QUAD_TOP_RIGHT,
-   QUAD_BOTTOM_RIGHT, QUAD_BOTTOM_RIGHT
-};
-
-static const unsigned char
-swizzle_top[4] = {
-   QUAD_TOP_LEFT,     QUAD_TOP_RIGHT,
-   QUAD_TOP_LEFT,     QUAD_TOP_RIGHT
-};
-
-static const unsigned char
-swizzle_bottom[4] = {
-   QUAD_BOTTOM_LEFT,  QUAD_BOTTOM_RIGHT,
-   QUAD_BOTTOM_LEFT,  QUAD_BOTTOM_RIGHT
-};
-
 static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
 {
    mask->bld = bld;
@@ -432,25 +404,6 @@ static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
    lp_exec_mask_update(mask);
 }
 
-static LLVMValueRef
-emit_ddx(struct lp_build_tgsi_soa_context *bld,
-         LLVMValueRef src)
-{
-   LLVMValueRef src_left  = lp_build_swizzle1_aos(&bld->base, src, swizzle_left);
-   LLVMValueRef src_right = lp_build_swizzle1_aos(&bld->base, src, swizzle_right);
-   return lp_build_sub(&bld->base, src_right, src_left);
-}
-
-
-static LLVMValueRef
-emit_ddy(struct lp_build_tgsi_soa_context *bld,
-         LLVMValueRef src)
-{
-   LLVMValueRef src_top    = lp_build_swizzle1_aos(&bld->base, src, swizzle_top);
-   LLVMValueRef src_bottom = lp_build_swizzle1_aos(&bld->base, src, swizzle_bottom);
-   return lp_build_sub(&bld->base, src_top, src_bottom);
-}
-
 static LLVMValueRef
 get_temp_ptr(struct lp_build_tgsi_soa_context *bld,
              unsigned index,
@@ -599,10 +552,10 @@ emit_fetch_deriv(
    /* TODO: use interpolation coeffs for inputs */
 
    if(ddx)
-      *ddx = emit_ddx(bld, src);
+      *ddx = lp_build_ddx(&bld->base, src);
 
    if(ddy)
-      *ddy = emit_ddy(bld, src);
+      *ddy = lp_build_ddy(&bld->base, src);
 }
 
 
@@ -842,8 +795,8 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
       unit = inst->Src[3].Register.Index;
    }  else {
       for (i = 0; i < num_coords; i++) {
-         ddx[i] = emit_ddx( bld, coords[i] );
-         ddy[i] = emit_ddy( bld, coords[i] );
+         ddx[i] = lp_build_ddx( &bld->base, coords[i] );
+         ddy[i] = lp_build_ddy( &bld->base, coords[i] );
       }
       unit = inst->Src[1].Register.Index;
    }