From 315f8daab1598a4de709d469a559b5aa09107404 Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Thu, 4 Nov 2010 11:42:55 +0000 Subject: [PATCH] llvmpipe: added llvm offset setup code --- src/gallium/drivers/llvmpipe/lp_context.h | 3 + src/gallium/drivers/llvmpipe/lp_state_setup.c | 179 +++++++++++++----- src/gallium/drivers/llvmpipe/lp_state_setup.h | 6 +- .../drivers/llvmpipe/lp_state_surface.c | 1 + 4 files changed, 143 insertions(+), 46 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 2230d500d2f..4515dbb0af1 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -113,6 +113,9 @@ struct llvmpipe_context { /** Which vertex shader output slot contains point size */ int psize_slot; + /**< minimum resolvable depth value, for polygon offset */ + double mrd; + /** The tiling engine */ struct lp_setup_context *setup; struct lp_setup_variant setup_variant; diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 83834946517..7751b7d6c37 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -30,10 +30,12 @@ #include "util/u_memory.h" #include "util/u_simple_list.h" #include "os/os_time.h" +#include "gallivm/lp_bld_arit.h" #include "gallivm/lp_bld_debug.h" #include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_intr.h" #include "gallivm/lp_bld_flow.h" +#include "gallivm/lp_bld_type.h" #include /* for LLVMVerifyFunction */ #include "lp_perf.h" @@ -74,15 +76,7 @@ struct lp_setup_args LLVMValueRef dy20_ooa; LLVMValueRef dy01_ooa; LLVMValueRef dx20_ooa; - LLVMValueRef dx01_ooa; - - /* For twoside calcs - */ - LLVMValueRef det; - LLVMValueRef sign; - LLVMValueRef bcolor_slot; - LLVMValueRef color_slot; - + LLVMValueRef dx01_ooa; }; static LLVMTypeRef type4f(void) @@ -204,7 +198,34 @@ vert_attrib(LLVMBuilderRef b, return LLVMBuildLoad(b, LLVMBuildGEP(b, vert, idx, 2, ""), name); } - +static LLVMValueRef +vert_clamp(LLVMBuilderRef b, + LLVMValueRef x, + LLVMValueRef min, + LLVMValueRef max, + LLVMValueRef clamp_ptr) +{ + struct lp_build_if_state if_state; + LLVMValueRef min_result = LLVMBuildFCmp(b, LLVMRealUGT, min, x, ""); + LLVMValueRef max_result = LLVMBuildFCmp(b, LLVMRealUGT, x, max, ""); + + lp_build_if(&if_state, b, min_result); + { + LLVMBuildStore(b, min, clamp_ptr); + } + lp_build_endif(&if_state); + lp_build_if(&if_state, b, max_result); + { + LLVMBuildStore(b, max, clamp_ptr); + } + lp_build_else(&if_state); + { + LLVMBuildStore(b, x, clamp_ptr); + } + lp_build_endif(&if_state); + + return LLVMBuildLoad(b, clamp_ptr,""); +} static void emit_coef4( LLVMBuilderRef b, @@ -481,15 +502,6 @@ init_args(LLVMBuilderRef b, args->y0_center = vec4f_from_scalar(b, y0_center, "y0_center_4f"); } -static void -set_args_attr(struct llvmpipe_context *lp, - struct lp_setup_args *args) -{ - args->color_slot = LLVMConstInt(LLVMInt32Type(), lp->color_slot, 0); - args->bcolor_slot = LLVMConstInt(LLVMInt32Type(), lp->bcolor_slot, 0); - args->sign = LLVMConstReal(LLVMFloatType(), (lp->rasterizer->front_ccw ? -1.0f : 1.0f)); -} - static void lp_twoside(LLVMBuilderRef b, struct lp_setup_args *args, @@ -499,32 +511,13 @@ lp_twoside(LLVMBuilderRef b, LLVMValueRef a0_old, a1_old, a2_old; LLVMValueRef a0_new, a1_new, a2_new; - - LLVMValueRef idx1 = args->color_slot; - LLVMValueRef idx2 = args->bcolor_slot; + + LLVMValueRef idx1 = LLVMConstInt(LLVMInt32Type(), key->color_slot, 0); + LLVMValueRef idx2 = LLVMConstInt(LLVMInt32Type(), key->bcolor_slot, 0); LLVMValueRef facing = args->facing; - LLVMValueRef front_facing = LLVMBuildICmp(b, LLVMIntEQ, facing, LLVMConstInt(LLVMInt32Type(), 0, 0), ""); /** need i1 for loop condition */ + LLVMValueRef front_facing = LLVMBuildICmp(b, LLVMIntEQ, facing, LLVMConstInt(LLVMInt32Type(), 0, 0), ""); /** need i1 for if condition */ -#if 0 -/*Probably can delete this, just tried to follow draw_pipe_twoside way of - calculating det*/ - /* edge vectors: e = v0 - v2, f = v1 - v2 */ - LLVMValueRef e = LLVMBuildFSub(b, args->v0, args->v2, "e"); - LLVMValueRef f = LLVMBuildFSub(b, args->v1, args->v2, "f"); - LLVMValueRef dx02 = vert_attrib(b, e, 0, 0, "dx02"); - LLVMValueRef dy02 = vert_attrib(b, e, 0, 1, "dy02"); - LLVMValueRef dx12 = vert_attrib(b, f, 0, 0, "dx12"); - LLVMValueRef dy12 = vert_attrib(b, f, 0, 1, "dy12"); - - /* det = cross(e,f).z */ - LLVMValueRef dx02_dy12 = LLVMBuildFMul(b, dx02, dy12, "dx02_dy12"); - LLVMValueRef dy02_dx12 = LLVMBuildFMul(b, dy02, dx12, "dy02_dx12"); - LLVMValueRef det = LLVMBuildFSub(b, dx02_dy12, dy02_dx12, "det"); - args->det = det; - LLVMValueRef result = LLVMBuildFMul(b, det, args->sign, "dy02_dx12"); -#endif - lp_build_if(&if_state, b, front_facing); { /* swap the front and back attrib values */ @@ -544,6 +537,97 @@ lp_twoside(LLVMBuilderRef b, } +static void +lp_do_offset_tri(LLVMBuilderRef b, + struct lp_setup_args *args, + const struct lp_setup_variant_key *key) +{ + struct lp_build_if_state if_state; + struct lp_build_context bld; + LLVMValueRef zoffset, mult; + LLVMValueRef z0_new, z1_new, z2_new; + LLVMValueRef dzdx0, dzdx, dzdy0, dzdy, max; + + LLVMValueRef idx[2]; + LLVMValueRef one = LLVMConstReal(LLVMFloatType(), 1.0); + LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0); + + /* edge vectors: e = v0 - v2, f = v1 - v2 */ + LLVMValueRef v0_x = vert_attrib(b, args->v0, 0, 0, "v0_x"); + LLVMValueRef v1_x = vert_attrib(b, args->v1, 0, 0, "v1_x"); + LLVMValueRef v2_x = vert_attrib(b, args->v2, 0, 0, "v2_x"); + LLVMValueRef v0_y = vert_attrib(b, args->v0, 0, 1, "v0_y"); + LLVMValueRef v1_y = vert_attrib(b, args->v1, 0, 1, "v1_y"); + LLVMValueRef v2_y = vert_attrib(b, args->v2, 0, 1, "v2_y"); + LLVMValueRef v0_z = vert_attrib(b, args->v0, 0, 2, "v0_z"); + LLVMValueRef v1_z = vert_attrib(b, args->v1, 0, 2, "v1_z"); + LLVMValueRef v2_z = vert_attrib(b, args->v2, 0, 2, "v2_z"); + + /* edge vectors: e = v0 - v2, f = v1 - v2 */ + LLVMValueRef dx02 = LLVMBuildFSub(b, v0_x, v2_x, "dx02"); + LLVMValueRef dy02 = LLVMBuildFSub(b, v0_y, v2_y, "dy02"); + LLVMValueRef dz02 = LLVMBuildFSub(b, v0_z, v2_z, "dz02"); + LLVMValueRef dx12 = LLVMBuildFSub(b, v1_x, v2_x, "dx12"); + LLVMValueRef dy12 = LLVMBuildFSub(b, v1_y, v2_y, "dy12"); + LLVMValueRef dz12 = LLVMBuildFSub(b, v1_z, v2_z, "dz12"); + + /* det = cross(e,f).z */ + LLVMValueRef dx02_dy12 = LLVMBuildFMul(b, dx02, dy12, "dx02_dy12"); + LLVMValueRef dy02_dx12 = LLVMBuildFMul(b, dy02, dx12, "dy02_dx12"); + LLVMValueRef det = LLVMBuildFSub(b, dx02_dy12, dy02_dx12, "det"); + LLVMValueRef inv_det = LLVMBuildFDiv(b, one, det, "inv_det"); + + /* (res1,res2) = cross(e,f).xy */ + LLVMValueRef dy02_dz12 = LLVMBuildFMul(b, dy02, dz12, "dy02_dz12"); + LLVMValueRef dz02_dy12 = LLVMBuildFMul(b, dz02, dy12, "dz02_dy12"); + LLVMValueRef dz02_dx12 = LLVMBuildFMul(b, dz02, dx12, "dz02_dx12"); + LLVMValueRef dx02_dz12 = LLVMBuildFMul(b, dx02, dz12, "dx02_dz12"); + LLVMValueRef res1 = LLVMBuildFSub(b, dy02_dz12, dz02_dy12, "res1"); + LLVMValueRef res2 = LLVMBuildFSub(b, dz02_dx12, dx02_dz12, "res2"); + + /* for the if-else functions phi's */ + LLVMValueRef zoffset_ptr = lp_build_alloca(b, LLVMFloatType(), ""); + LLVMValueRef clamp_ptr = lp_build_alloca(b, LLVMFloatType(), ""); + + /* dzdx = fabsf(res1 * inv_det), dydx = fabsf(res2 * inv_det)*/ + lp_build_context_init(&bld, b, lp_type_float(32)); + dzdx0 = LLVMBuildFMul(b, res1, inv_det, "dzdx"); + dzdx = lp_build_abs(&bld, dzdx0); + dzdy0 = LLVMBuildFMul(b, res2, inv_det, "dzdy"); + dzdy = lp_build_abs(&bld, dzdy0); + + /* zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale */ + max = LLVMBuildFCmp(b, LLVMRealUGT, dzdx, dzdy, ""); + lp_build_if(&if_state, b, max); + { + mult = LLVMBuildFMul(b, dzdx, LLVMConstReal(LLVMFloatType(), key->scale), ""); + zoffset = LLVMBuildFAdd(b, LLVMConstReal(LLVMFloatType(), key->units), mult, "zoffset"); + LLVMBuildStore(b, zoffset, zoffset_ptr); + } + lp_build_else(&if_state); + { + mult = LLVMBuildFMul(b, dzdy, LLVMConstReal(LLVMFloatType(), key->scale), ""); + zoffset = LLVMBuildFAdd(b, LLVMConstReal(LLVMFloatType(), key->units), mult, "zoffset"); + LLVMBuildStore(b, zoffset, zoffset_ptr); + } + lp_build_endif(&if_state); + + zoffset = LLVMBuildLoad(b, zoffset_ptr,""); + + /* clamp and do offset */ + z0_new = vert_clamp(b, LLVMBuildFAdd(b, v0_z, zoffset, ""), zero, one, clamp_ptr); + z1_new = vert_clamp(b, LLVMBuildFAdd(b, v1_z, zoffset, ""), zero, one, clamp_ptr); + z2_new = vert_clamp(b, LLVMBuildFAdd(b, v2_z, zoffset, ""), zero, one, clamp_ptr); + + /* store back new offsetted z values */ + idx[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); + idx[1] = LLVMConstInt(LLVMInt32Type(), 2, 0); + LLVMBuildStore(b, z0_new, LLVMBuildGEP(b, args->v0, idx, 2, "")); + LLVMBuildStore(b, z1_new, LLVMBuildGEP(b, args->v1, idx, 2, "")); + LLVMBuildStore(b, z2_new, LLVMBuildGEP(b, args->v2, idx, 2, "")); + +} + /** * Generate the runtime callable function for the coefficient calculation. @@ -630,9 +714,11 @@ generate_setup_variant(struct llvmpipe_screen *screen, set_noalias(builder, variant->function, arg_types, Elements(arg_types)); init_args(builder, &args, variant); if (variant->key.twoside){ - set_args_attr(lp, &args); lp_twoside(builder, &args, &variant->key); } + if (variant->key.scale){ + lp_do_offset_tri(builder, &args, &variant->key); + } emit_tri_coef(builder, &variant->key, &args); lp_emit_emms(builder); @@ -685,9 +771,12 @@ lp_make_setup_variant_key(struct llvmpipe_context *lp, key->pixel_center_half = lp->rasterizer->gl_rasterization_rules; key->twoside = lp->rasterizer->light_twoside; key->size = Offset(struct lp_setup_variant_key, - inputs[key->num_inputs]); + inputs[key->num_inputs]); + key->color_slot = lp->color_slot; + key->bcolor_slot = lp->bcolor_slot; + key->units = (float) (lp->rasterizer->offset_units * lp->mrd); + key->scale = lp->rasterizer->offset_scale; key->pad = 0; - memcpy(key->inputs, fs->inputs, key->num_inputs * sizeof key->inputs[0]); for (i = 0; i < key->num_inputs; i++) { if (key->inputs[i].interp == LP_INTERP_COLOR) { diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.h b/src/gallium/drivers/llvmpipe/lp_state_setup.h index 4079fb71f66..40fb8ef4282 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h @@ -19,8 +19,12 @@ struct lp_setup_variant_key { unsigned flatshade_first:1; unsigned pixel_center_half:1; unsigned twoside:1; - unsigned pad:6; + unsigned color_slot:8; + unsigned bcolor_slot:8; unsigned size:16; + unsigned pad:21; + float units; + float scale; struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; }; diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c index cd1a5b19803..375ceb2b942 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -77,6 +77,7 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe, else { mrd = 0.00002; } + lp->mrd = mrd; draw_set_mrd(lp->draw, mrd); } -- 2.30.2