summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/gallivm
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/gallivm')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.c39
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.h4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.c18
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.cpp23
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_quad.c101
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_quad.h96
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c12
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c228
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c57
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.c20
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.h12
13 files changed, 396 insertions, 220 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 47aa9aa362..d926b2de18 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -54,12 +54,10 @@
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_intr.h"
-#include "lp_bld_init.h" /* for lp_build_engine */
#include "lp_bld_logic.h"
#include "lp_bld_pack.h"
#include "lp_bld_debug.h"
#include "lp_bld_arit.h"
-#include "lp_bld_printf.h"
/**
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c
index 031ce9d1a3..e42ff31ac7 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c
@@ -280,34 +280,45 @@ lp_build_one(struct lp_type type)
/**
- * Build constant-valued vector from a scalar value.
+ * Build constant-valued element from a scalar value.
*/
LLVMValueRef
-lp_build_const_vec(struct lp_type type,
- double val)
+lp_build_const_elem(struct lp_type type,
+ double val)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
- LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
- unsigned i;
-
- assert(type.length <= LP_MAX_VECTOR_LENGTH);
+ LLVMValueRef elem;
if(type.floating) {
- elems[0] = LLVMConstReal(elem_type, val);
+ elem = LLVMConstReal(elem_type, val);
}
else {
double dscale = lp_const_scale(type);
- elems[0] = LLVMConstInt(elem_type, val*dscale + 0.5, 0);
+ elem = LLVMConstInt(elem_type, val*dscale + 0.5, 0);
}
- if (type.length == 1)
- return elems[0];
+ return elem;
+}
- for(i = 1; i < type.length; ++i)
- elems[i] = elems[0];
- return LLVMConstVector(elems, type.length);
+/**
+ * Build constant-valued vector from a scalar value.
+ */
+LLVMValueRef
+lp_build_const_vec(struct lp_type type,
+ double val)
+{
+ if (type.length == 1) {
+ return lp_build_const_elem(type, val);
+ } else {
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+ elems[0] = lp_build_const_elem(type, val);
+ for(i = 1; i < type.length; ++i)
+ elems[i] = elems[0];
+ return LLVMConstVector(elems, type.length);
+ }
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.h b/src/gallium/auxiliary/gallivm/lp_bld_const.h
index 9ca2f0664e..d46b9f882b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.h
@@ -85,6 +85,10 @@ lp_build_one(struct lp_type type);
LLVMValueRef
+lp_build_const_elem(struct lp_type type,
+ double val);
+
+LLVMValueRef
lp_build_const_vec(struct lp_type type, double val);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
index 823a8ec7b7..5bc9c741a8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
@@ -38,7 +38,7 @@
#include "lp_bld_flow.h"
-#define LP_BUILD_FLOW_MAX_VARIABLES 32
+#define LP_BUILD_FLOW_MAX_VARIABLES 64
#define LP_BUILD_FLOW_MAX_DEPTH 32
/**
@@ -407,6 +407,7 @@ lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow,
/* for each variable, update the Phi node with a (variable, block) pair */
for(i = 0; i < skip->num_variables; ++i) {
assert(*flow->variables[i]);
+ assert(LLVMTypeOf(skip->phi[i]) == LLVMTypeOf(*flow->variables[i]));
LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
}
@@ -433,6 +434,7 @@ lp_build_flow_skip_end(struct lp_build_flow_context *flow)
/* add (variable, block) tuples to the phi nodes */
for(i = 0; i < skip->num_variables; ++i) {
assert(*flow->variables[i]);
+ assert(LLVMTypeOf(skip->phi[i]) == LLVMTypeOf(*flow->variables[i]));
LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
*flow->variables[i] = skip->phi[i];
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index e02a45114b..0a690ea747 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -37,11 +37,11 @@
unsigned gallivm_debug = 0;
static const struct debug_named_value lp_bld_debug_flags[] = {
- { "tgsi", GALLIVM_DEBUG_TGSI },
- { "ir", GALLIVM_DEBUG_IR },
- { "asm", GALLIVM_DEBUG_ASM },
- { "nopt", GALLIVM_DEBUG_NO_OPT },
- {NULL, 0}
+ { "tgsi", GALLIVM_DEBUG_TGSI, NULL },
+ { "ir", GALLIVM_DEBUG_IR, NULL },
+ { "asm", GALLIVM_DEBUG_ASM, NULL },
+ { "nopt", GALLIVM_DEBUG_NO_OPT, NULL },
+ DEBUG_NAMED_VALUE_END
};
#endif
@@ -75,6 +75,10 @@ enum LLVM_CodeGenOpt_Level {
};
+extern void
+lp_register_oprofile_jit_event_listener(LLVMExecutionEngineRef EE);
+
+
void
lp_build_init(void)
{
@@ -109,6 +113,10 @@ lp_build_init(void)
LLVMDisposeMessage(error);
assert(0);
}
+
+#if defined(DEBUG) || defined(PROFILE)
+ lp_register_oprofile_jit_event_listener(lp_build_engine);
+#endif
}
if (!lp_build_target)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index db0ca606e5..f004c0ae45 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -34,7 +34,10 @@
#define __STDC_CONSTANT_MACROS
#endif
-#include "llvm-c/Core.h"
+#include <llvm-c/Core.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+#include <llvm/ExecutionEngine/JITEventListener.h>
#include "pipe/p_config.h"
#include "util/u_debug.h"
@@ -98,3 +101,21 @@ lp_debug_dump_value(LLVMValueRef value)
#endif
+
+
+/**
+ * Register the engine with oprofile.
+ *
+ * This allows to see the LLVM IR function names in oprofile output.
+ *
+ * To actually work LLVM needs to be built with the --with-oprofile configure
+ * option.
+ *
+ * Also a oprofile:oprofile user:group is necessary. Which is not created by
+ * default on some distributions.
+ */
+extern "C" void
+lp_register_oprofile_jit_event_listener(LLVMExecutionEngineRef EE)
+{
+ llvm::unwrap(EE)->RegisterJITEventListener(llvm::createOProfileJITEventListener());
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_quad.c b/src/gallium/auxiliary/gallivm/lp_bld_quad.c
new file mode 100644
index 0000000000..38fd5a39ef
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_quad.c
@@ -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
index 0000000000..b799291292
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_quad.h
@@ -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_ */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index c7f9b1083b..946c23e317 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -92,7 +92,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
state->wrap_r = sampler->wrap_r;
state->min_img_filter = sampler->min_img_filter;
state->mag_img_filter = sampler->mag_img_filter;
- if (texture->last_level) {
+ if (view->last_level) {
state->min_mip_filter = sampler->min_mip_filter;
} else {
state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
@@ -105,8 +105,14 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
state->normalized_coords = sampler->normalized_coords;
state->lod_bias = sampler->lod_bias;
- state->min_lod = sampler->min_lod;
- state->max_lod = sampler->max_lod;
+ if (!view->last_level &&
+ sampler->min_img_filter == sampler->mag_img_filter) {
+ state->min_lod = 0.0f;
+ state->max_lod = 0.0f;
+ } else {
+ state->min_lod = MAX2(sampler->min_lod, 0.0f);
+ state->max_lod = sampler->max_lod;
+ }
state->border_color[0] = sampler->border_color[0];
state->border_color[1] = sampler->border_color[1];
state->border_color[2] = sampler->border_color[2];
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index bc7213db8b..84c04fe272 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -415,10 +415,8 @@ is_simple_wrap_mode(unsigned mode)
{
switch (mode) {
case PIPE_TEX_WRAP_REPEAT:
- case PIPE_TEX_WRAP_CLAMP:
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
return TRUE;
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
default:
return FALSE;
}
@@ -455,24 +453,17 @@ lp_build_sample_wrap_int(struct lp_build_sample_context *bld,
coord = LLVMBuildURem(bld->builder, coord, length, "");
break;
- case PIPE_TEX_WRAP_CLAMP:
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero);
coord = lp_build_min(int_coord_bld, coord, length_minus_one);
break;
+ case PIPE_TEX_WRAP_CLAMP:
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
case PIPE_TEX_WRAP_MIRROR_REPEAT:
case PIPE_TEX_WRAP_MIRROR_CLAMP:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- /* FIXME */
- _debug_printf("llvmpipe: failed to translate texture wrap mode %s\n",
- util_dump_tex_wrap(wrap_mode, TRUE));
- coord = lp_build_max(uint_coord_bld, coord, uint_coord_bld->zero);
- coord = lp_build_min(uint_coord_bld, coord, length_minus_one);
- break;
-
default:
assert(0);
}
@@ -500,11 +491,9 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
- LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
LLVMValueRef coord0, coord1, weight;
switch(wrap_mode) {
@@ -532,16 +521,18 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_CLAMP:
if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
}
+
+ /* clamp to [0, length] */
+ coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f);
+
+ coord = lp_build_sub(coord_bld, coord, half);
+
weight = lp_build_fract(coord_bld, coord);
- coord0 = lp_build_clamp(coord_bld, coord, coord_bld->zero,
- length_f_minus_one);
- coord1 = lp_build_add(coord_bld, coord, coord_bld->one);
- coord1 = lp_build_clamp(coord_bld, coord1, coord_bld->zero,
- length_f_minus_one);
- coord0 = lp_build_ifloor(coord_bld, coord0);
- coord1 = lp_build_ifloor(coord_bld, coord1);
+ coord0 = lp_build_ifloor(coord_bld, coord);
+ coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
@@ -555,7 +546,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
else {
LLVMValueRef min, max;
/* clamp to [0.5, length - 0.5] */
- min = lp_build_const_vec(coord_bld->type, 0.5F);
+ min = half;
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
}
@@ -574,25 +565,14 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
{
LLVMValueRef min, max;
if (bld->static_state->normalized_coords) {
- /* min = -1.0 / (2 * length) = -0.5 / length */
- min = lp_build_mul(coord_bld,
- lp_build_const_vec(coord_bld->type, -0.5F),
- lp_build_rcp(coord_bld, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
- /* scale coord to length (and sub 0.5?) */
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_sub(coord_bld, coord, half);
- }
- else {
- /* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_vec(coord_bld->type, -0.5F);
- max = lp_build_sub(coord_bld, length_f, min);
- coord = lp_build_clamp(coord_bld, coord, min, max);
- coord = lp_build_sub(coord_bld, coord, half);
}
+ /* clamp to [-0.5, length + 0.5] */
+ min = lp_build_const_vec(coord_bld->type, -0.5F);
+ max = lp_build_sub(coord_bld, length_f, min);
+ coord = lp_build_clamp(coord_bld, coord, min, max);
+ coord = lp_build_sub(coord_bld, coord, half);
/* compute lerp weight */
weight = lp_build_fract(coord_bld, coord);
/* convert to int */
@@ -623,35 +603,41 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
+ coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_clamp(coord_bld, coord, min, max);
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- if(0)coord = lp_build_sub(coord_bld, coord, half);
- weight = lp_build_fract(coord_bld, coord);
- coord0 = lp_build_ifloor(coord_bld, coord);
- coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
}
+
+ /* clamp to [0, length] */
+ coord = lp_build_min(coord_bld, coord, length_f);
+
+ coord = lp_build_sub(coord_bld, coord, half);
+
+ weight = lp_build_fract(coord_bld, coord);
+ coord0 = lp_build_ifloor(coord_bld, coord);
+ coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
{
LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
coord = lp_build_abs(coord_bld, coord);
+
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
+ coord = lp_build_mul(coord_bld, coord, length_f);
+ }
+
+ /* clamp to [0.5, length - 0.5] */
+ min = half;
+ max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
- coord = lp_build_mul(coord_bld, coord, length_f);
+
coord = lp_build_sub(coord_bld, coord, half);
+
weight = lp_build_fract(coord_bld, coord);
coord0 = lp_build_ifloor(coord_bld, coord);
coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
@@ -661,17 +647,21 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
{
LLVMValueRef min, max;
- /* min = -1.0 / (2 * length) = -0.5 / length */
- min = lp_build_mul(coord_bld,
- lp_build_const_vec(coord_bld->type, -0.5F),
- lp_build_rcp(coord_bld, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
coord = lp_build_abs(coord_bld, coord);
+
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
+ coord = lp_build_mul(coord_bld, coord, length_f);
+ }
+
+ /* clamp to [-0.5, length + 0.5] */
+ min = lp_build_negate(coord_bld, half);
+ max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
- coord = lp_build_mul(coord_bld, coord, length_f);
+
coord = lp_build_sub(coord_bld, coord, half);
+
weight = lp_build_fract(coord_bld, coord);
coord0 = lp_build_ifloor(coord_bld, coord);
coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
@@ -708,10 +698,8 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
- LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
LLVMValueRef icoord;
switch(wrap_mode) {
@@ -727,120 +715,80 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
break;
case PIPE_TEX_WRAP_CLAMP:
- /* mul by size */
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
}
+
/* floor */
icoord = lp_build_ifloor(coord_bld, coord);
- /* clamp to [0, size-1]. Note: int coord builder type */
+
+ /* clamp to [0, length - 1]. */
icoord = lp_build_clamp(int_coord_bld, icoord, int_coord_bld->zero,
length_minus_one);
break;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- {
- LLVMValueRef min, max;
- if (bld->static_state->normalized_coords) {
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
- /* scale coord to length */
- coord = lp_build_mul(coord_bld, coord, length_f);
- }
- else {
- /* clamp to [0.5, length - 0.5] */
- min = lp_build_const_vec(coord_bld->type, 0.5F);
- max = lp_build_sub(coord_bld, length_f, min);
- }
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
- }
- break;
-
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
/* Note: this is the same as CLAMP_TO_EDGE, except min = -min */
{
LLVMValueRef min, max;
+
if (bld->static_state->normalized_coords) {
- /* min = -1.0 / (2 * length) = -0.5 / length */
- min = lp_build_mul(coord_bld,
- lp_build_const_vec(coord_bld->type, -0.5F),
- lp_build_rcp(coord_bld, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
/* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
}
- else {
- /* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_vec(coord_bld->type, -0.5F);
- max = lp_build_sub(coord_bld, length_f, min);
- }
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
+
icoord = lp_build_ifloor(coord_bld, coord);
+
+ /* clamp to [-1, length] */
+ min = lp_build_negate(int_coord_bld, int_coord_bld->one);
+ max = length;
+ icoord = lp_build_clamp(int_coord_bld, icoord, min, max);
}
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
+ /* compute mirror function */
+ coord = lp_build_coord_mirror(bld, coord);
- /* compute mirror function */
- coord = lp_build_coord_mirror(bld, coord);
+ /* scale coord to length */
+ assert(bld->static_state->normalized_coords);
+ coord = lp_build_mul(coord_bld, coord, length_f);
- /* scale coord to length */
- coord = lp_build_mul(coord_bld, coord, length_f);
+ icoord = lp_build_ifloor(coord_bld, coord);
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
- }
+ /* clamp to [0, length - 1] */
+ icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
- coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f_minus_one);
- icoord = lp_build_ifloor(coord_bld, coord);
- break;
-
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
+ coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_abs(coord_bld, coord);
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
}
+
+ icoord = lp_build_ifloor(coord_bld, coord);
+
+ /* clamp to [0, length - 1] */
+ icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- min = lp_build_negate(coord_bld, min);
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
+ coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_abs(coord_bld, coord);
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
}
+
+ icoord = lp_build_ifloor(coord_bld, coord);
+
+ /* clamp to [0, length] */
+ icoord = lp_build_min(int_coord_bld, icoord, length);
break;
default:
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 40ea94c493..ea949a1363 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -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"
@@ -76,11 +77,6 @@
#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;
@@ -433,25 +405,6 @@ static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
}
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,
unsigned chan,
@@ -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;
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.c b/src/gallium/auxiliary/gallivm/lp_bld_type.c
index aac3a57bc7..06f1aae6dc 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.c
@@ -372,7 +372,23 @@ lp_build_context_init(struct lp_build_context *bld,
{
bld->builder = builder;
bld->type = type;
- bld->undef = lp_build_undef(type);
- bld->zero = lp_build_zero(type);
+
+ bld->int_elem_type = lp_build_int_elem_type(type);
+ if (type.floating)
+ bld->elem_type = lp_build_elem_type(type);
+ else
+ bld->elem_type = bld->int_elem_type;
+
+ if (type.length == 1) {
+ bld->int_vec_type = bld->int_elem_type;
+ bld->vec_type = bld->elem_type;
+ }
+ else {
+ bld->int_vec_type = LLVMVectorType(bld->int_elem_type, type.length);
+ bld->vec_type = LLVMVectorType(bld->elem_type, type.length);
+ }
+
+ bld->undef = LLVMGetUndef(bld->vec_type);
+ bld->zero = LLVMConstNull(bld->vec_type);
bld->one = lp_build_one(type);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h
index 17819d4d32..df77ef2155 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h
@@ -129,6 +129,18 @@ struct lp_build_context
struct lp_type type;
/** Same as lp_build_undef(type) */
+ LLVMTypeRef elem_type;
+
+ /** Same as lp_build_undef(type) */
+ LLVMTypeRef vec_type;
+
+ /** Same as lp_build_undef(type) */
+ LLVMTypeRef int_elem_type;
+
+ /** Same as lp_build_undef(type) */
+ LLVMTypeRef int_vec_type;
+
+ /** Same as lp_build_undef(type) */
LLVMValueRef undef;
/** Same as lp_build_zero(type) */