diff options
Diffstat (limited to 'src/gallium/auxiliary/gallivm')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_arit.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_const.c | 39 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_const.h | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_flow.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_init.c | 18 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_misc.cpp | 23 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_quad.c | 101 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_quad.h | 96 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample.c | 12 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 228 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 57 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_type.c | 20 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_type.h | 12 |
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], ¤t_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], ¤t_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) */ |