From 64611e086dbefa2003773ab541c0381b5713e18d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 3 Aug 2009 22:31:08 +0100 Subject: [PATCH] llvmpipe: Separate constant building. --- src/gallium/drivers/llvmpipe/SConscript | 1 + src/gallium/drivers/llvmpipe/lp_bld_arit.c | 107 +-------------- src/gallium/drivers/llvmpipe/lp_bld_arit.h | 39 ++---- src/gallium/drivers/llvmpipe/lp_bld_blend.c | 5 +- src/gallium/drivers/llvmpipe/lp_bld_const.c | 145 ++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_bld_const.h | 64 +++++++++ 6 files changed, 226 insertions(+), 135 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_bld_const.c create mode 100644 src/gallium/drivers/llvmpipe/lp_bld_const.h diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 615a885cc5f..71c55a93ab9 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -11,6 +11,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_fs_sse.c', 'lp_fs_llvm.c', 'lp_bld_arit.c', + 'lp_bld_const.c', 'lp_bld_pack.c', 'lp_bld_unpack.c', 'lp_bld_load.c', diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c index 36b266a45a6..5dc1b7c968b 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c @@ -45,117 +45,12 @@ */ -#include "pipe/p_state.h" +#include "util/u_debug.h" #include "lp_bld_type.h" #include "lp_bld_arit.h" -LLVMValueRef -lp_build_undef(union lp_type type) -{ - LLVMTypeRef vec_type = lp_build_vec_type(type); - return LLVMGetUndef(vec_type); -} - - -LLVMValueRef -lp_build_zero(union lp_type type) -{ - LLVMTypeRef vec_type = lp_build_vec_type(type); - return LLVMConstNull(vec_type); -} - - -LLVMValueRef -lp_build_one(union lp_type type) -{ - LLVMTypeRef elem_type; - LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; - unsigned i; - - assert(type.length <= LP_MAX_VECTOR_LENGTH); - - elem_type = lp_build_elem_type(type); - - if(type.floating) - elems[0] = LLVMConstReal(elem_type, 1.0); - else if(type.fixed) - elems[0] = LLVMConstInt(elem_type, 1LL << (type.width/2), 0); - else if(!type.norm) - elems[0] = LLVMConstInt(elem_type, 1, 0); - else { - /* special case' -- 1.0 for normalized types is more easily attained if - * we start with a vector consisting of all bits set */ - LLVMTypeRef vec_type = LLVMVectorType(elem_type, type.length); - LLVMValueRef vec = LLVMConstAllOnes(vec_type); - - if(type.sign) - vec = LLVMConstLShr(vec, LLVMConstInt(LLVMInt32Type(), 1, 0)); - - return vec; - } - - for(i = 1; i < type.length; ++i) - elems[i] = elems[0]; - - return LLVMConstVector(elems, type.length); -} - - -LLVMValueRef -lp_build_const_aos(union lp_type type, - double r, double g, double b, double a, - const unsigned char *swizzle) -{ - const unsigned char default_swizzle[4] = {0, 1, 2, 3}; - LLVMTypeRef elem_type; - LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; - unsigned i; - - assert(type.length % 4 == 0); - assert(type.length <= LP_MAX_VECTOR_LENGTH); - - elem_type = lp_build_elem_type(type); - - if(swizzle == NULL) - swizzle = default_swizzle; - - if(type.floating) { - elems[swizzle[0]] = LLVMConstReal(elem_type, r); - elems[swizzle[1]] = LLVMConstReal(elem_type, g); - elems[swizzle[2]] = LLVMConstReal(elem_type, b); - elems[swizzle[3]] = LLVMConstReal(elem_type, a); - } - else { - unsigned shift; - long long llscale; - double dscale; - - if(type.fixed) - shift = type.width/2; - else if(type.norm) - shift = type.sign ? type.width - 1 : type.width; - else - shift = 0; - - llscale = (long long)1 << shift; - dscale = (double)llscale; - assert((long long)dscale == llscale); - - elems[swizzle[0]] = LLVMConstInt(elem_type, r*dscale + 0.5, 0); - elems[swizzle[1]] = LLVMConstInt(elem_type, g*dscale + 0.5, 0); - elems[swizzle[2]] = LLVMConstInt(elem_type, b*dscale + 0.5, 0); - elems[swizzle[3]] = LLVMConstInt(elem_type, a*dscale + 0.5, 0); - } - - for(i = 4; i < type.length; ++i) - elems[i] = elems[i % 4]; - - return LLVMConstVector(elems, type.length); -} - - static LLVMValueRef lp_build_intrinsic_binary(LLVMBuilderRef builder, const char *name, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.h b/src/gallium/drivers/llvmpipe/lp_bld_arit.h index c437d2bcd00..cec54a257f7 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.h @@ -43,43 +43,28 @@ union lp_type type; -/* - * Constants - */ - - -LLVMValueRef -lp_build_undef(union lp_type type); - - -LLVMValueRef -lp_build_zero(union lp_type type); - - -LLVMValueRef -lp_build_one(union lp_type type); - - -LLVMValueRef -lp_build_const_aos(union lp_type type, - double r, double g, double b, double a, - const unsigned char *swizzle); - -/* - * Basic arithmetic - */ - - /** + * We need most of the information here in order to correctly and efficiently + * translate an arithmetic operation into LLVM IR. Putting it here avoids the + * trouble of passing it as parameters. */ struct lp_build_context { LLVMBuilderRef builder; + /** + * This not only describes the input/output LLVM types, but also whether + * to normalize/clamp the results. + */ union lp_type type; + /** Same as lp_build_undef(type) */ LLVMValueRef undef; + + /** Same as lp_build_zero(type) */ LLVMValueRef zero; + + /** Same as lp_build_one(type) */ LLVMValueRef one; }; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.c b/src/gallium/drivers/llvmpipe/lp_bld_blend.c index 2c5e67418fb..90afe2e6b67 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.c @@ -41,12 +41,13 @@ #include "lp_bld.h" #include "lp_bld_type.h" +#include "lp_bld_const.h" #include "lp_bld_arit.h" /** - * We may the same bld several times, so we keep them here to avoid - * recomputing them. Also reusing the bld allows us to do simplifications + * We may the same values several times, so we keep them here to avoid + * recomputing them. Also reusing the values allows us to do simplifications * that LLVM optimization passes wouldn't normally be able to do. */ struct lp_build_blend_context diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.c b/src/gallium/drivers/llvmpipe/lp_bld_const.c new file mode 100644 index 00000000000..44fcc467f40 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bld_const.c @@ -0,0 +1,145 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +/** + * @file + * Helper functions for constant building. + * + * @author Jose Fonseca + */ + + +#include "util/u_debug.h" + +#include "lp_bld_type.h" +#include "lp_bld_const.h" + + +LLVMValueRef +lp_build_undef(union lp_type type) +{ + LLVMTypeRef vec_type = lp_build_vec_type(type); + return LLVMGetUndef(vec_type); +} + + +LLVMValueRef +lp_build_zero(union lp_type type) +{ + LLVMTypeRef vec_type = lp_build_vec_type(type); + return LLVMConstNull(vec_type); +} + + +LLVMValueRef +lp_build_one(union lp_type type) +{ + LLVMTypeRef elem_type; + LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; + unsigned i; + + assert(type.length <= LP_MAX_VECTOR_LENGTH); + + elem_type = lp_build_elem_type(type); + + if(type.floating) + elems[0] = LLVMConstReal(elem_type, 1.0); + else if(type.fixed) + elems[0] = LLVMConstInt(elem_type, 1LL << (type.width/2), 0); + else if(!type.norm) + elems[0] = LLVMConstInt(elem_type, 1, 0); + else { + /* special case' -- 1.0 for normalized types is more easily attained if + * we start with a vector consisting of all bits set */ + LLVMTypeRef vec_type = LLVMVectorType(elem_type, type.length); + LLVMValueRef vec = LLVMConstAllOnes(vec_type); + + if(type.sign) + vec = LLVMConstLShr(vec, LLVMConstInt(LLVMInt32Type(), 1, 0)); + + return vec; + } + + for(i = 1; i < type.length; ++i) + elems[i] = elems[0]; + + return LLVMConstVector(elems, type.length); +} + + +LLVMValueRef +lp_build_const_aos(union lp_type type, + double r, double g, double b, double a, + const unsigned char *swizzle) +{ + const unsigned char default_swizzle[4] = {0, 1, 2, 3}; + LLVMTypeRef elem_type; + LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; + unsigned i; + + assert(type.length % 4 == 0); + assert(type.length <= LP_MAX_VECTOR_LENGTH); + + elem_type = lp_build_elem_type(type); + + if(swizzle == NULL) + swizzle = default_swizzle; + + if(type.floating) { + elems[swizzle[0]] = LLVMConstReal(elem_type, r); + elems[swizzle[1]] = LLVMConstReal(elem_type, g); + elems[swizzle[2]] = LLVMConstReal(elem_type, b); + elems[swizzle[3]] = LLVMConstReal(elem_type, a); + } + else { + unsigned shift; + long long llscale; + double dscale; + + if(type.fixed) + shift = type.width/2; + else if(type.norm) + shift = type.sign ? type.width - 1 : type.width; + else + shift = 0; + + llscale = (long long)1 << shift; + dscale = (double)llscale; + assert((long long)dscale == llscale); + + elems[swizzle[0]] = LLVMConstInt(elem_type, r*dscale + 0.5, 0); + elems[swizzle[1]] = LLVMConstInt(elem_type, g*dscale + 0.5, 0); + elems[swizzle[2]] = LLVMConstInt(elem_type, b*dscale + 0.5, 0); + elems[swizzle[3]] = LLVMConstInt(elem_type, a*dscale + 0.5, 0); + } + + for(i = 4; i < type.length; ++i) + elems[i] = elems[i % 4]; + + return LLVMConstVector(elems, type.length); +} diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.h b/src/gallium/drivers/llvmpipe/lp_bld_const.h new file mode 100644 index 00000000000..f2e5deca944 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bld_const.h @@ -0,0 +1,64 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * @file + * Helper functions for constant building. + * + * @author Jose Fonseca + */ + + +#ifndef LP_BLD_CONST_H +#define LP_BLD_CONST_H + + +#include + + +union lp_type type; + + +LLVMValueRef +lp_build_undef(union lp_type type); + + +LLVMValueRef +lp_build_zero(union lp_type type); + + +LLVMValueRef +lp_build_one(union lp_type type); + + +LLVMValueRef +lp_build_const_aos(union lp_type type, + double r, double g, double b, double a, + const unsigned char *swizzle); + + +#endif /* !LP_BLD_CONST_H */ -- 2.30.2