From a1ca5ac7c27c8bc3e294b50ab9ad340095f3030d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 22 Oct 2010 18:58:36 +0100 Subject: llvmpipe: turn off draw offset/twoside when we can handle it --- src/gallium/drivers/llvmpipe/lp_state_rasterizer.c | 99 ++++++++++++++++------ 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c index dbd73812e4..574f9e940e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c @@ -32,16 +32,64 @@ #include "lp_setup.h" #include "draw/draw_context.h" +struct lp_rast_state { + struct pipe_rasterizer_state lp_state; + struct pipe_rasterizer_state draw_state; +}; + +/* State which might be handled in either the draw module or locally. + * This function is used to turn that state off in one of the two + * places. + */ +static void +clear_flags(struct pipe_rasterizer_state *rast) +{ + rast->light_twoside = 0; + rast->offset_tri = 0; +} + static void * llvmpipe_create_rasterizer_state(struct pipe_context *pipe, const struct pipe_rasterizer_state *rast) { - /* We do nothing special with rasterizer state. - * The CSO handle is just a pointer to a pipe_rasterizer_state object. + boolean need_pipeline; + + /* Partition rasterizer state into what we want the draw module to + * handle, and what we'll look after ourselves. + */ + struct lp_rast_state *state = MALLOC_STRUCT(lp_rast_state); + if (state == NULL) + return NULL; + + memcpy(&state->draw_state, rast, sizeof *rast); + memcpy(&state->lp_state, rast, sizeof *rast); + + /* We rely on draw module to do unfilled polyons, AA lines and + * points and stipple. + * + * Over time, reduce this list of conditions, and expand the list + * of flags which get cleared in clear_flags(). */ - return mem_dup(rast, sizeof(*rast)); + need_pipeline = (rast->fill_front != PIPE_POLYGON_MODE_FILL || + rast->fill_back != PIPE_POLYGON_MODE_FILL || + rast->point_smooth || + rast->line_smooth || + rast->line_stipple_enable || + rast->poly_stipple_enable); + + /* If not using the pipeline, clear out the flags which we can + * handle ourselves. If we *are* using the pipeline, do everything + * on the pipeline and clear those flags on our internal copy of + * the state. + */ + if (need_pipeline) + clear_flags(&state->lp_state); + else + clear_flags(&state->draw_state); + + return state; } @@ -50,36 +98,33 @@ static void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - const struct pipe_rasterizer_state *rasterizer = - (const struct pipe_rasterizer_state *) handle; - - if (llvmpipe->rasterizer == rasterizer) - return; + const struct lp_rast_state *state = + (const struct lp_rast_state *) handle; - /* pass-through to draw module */ - draw_set_rasterizer_state(llvmpipe->draw, rasterizer, handle); + if (state) { + llvmpipe->rasterizer = &state->lp_state; + draw_set_rasterizer_state(llvmpipe->draw, &state->draw_state, handle); - llvmpipe->rasterizer = rasterizer; - - /* Note: we can immediately set the triangle state here and - * not worry about binning because we handle culling during - * triangle setup, not when rasterizing the bins. - */ - if (llvmpipe->rasterizer) { + /* XXX: just pass lp_state directly to setup. + */ lp_setup_set_triangle_state( llvmpipe->setup, - llvmpipe->rasterizer->cull_face, - llvmpipe->rasterizer->front_ccw, - llvmpipe->rasterizer->scissor, - llvmpipe->rasterizer->gl_rasterization_rules); + state->lp_state.cull_face, + state->lp_state.front_ccw, + state->lp_state.scissor, + state->lp_state.gl_rasterization_rules); lp_setup_set_flatshade_first( llvmpipe->setup, - llvmpipe->rasterizer->flatshade_first); + state->lp_state.flatshade_first); lp_setup_set_line_state( llvmpipe->setup, - llvmpipe->rasterizer->line_width); + state->lp_state.line_width); lp_setup_set_point_state( llvmpipe->setup, - llvmpipe->rasterizer->point_size, - llvmpipe->rasterizer->point_size_per_vertex, - llvmpipe->rasterizer->sprite_coord_enable, - llvmpipe->rasterizer->sprite_coord_mode); + state->lp_state.point_size, + state->lp_state.point_size_per_vertex, + state->lp_state.sprite_coord_enable, + state->lp_state.sprite_coord_mode); + } + else { + llvmpipe->rasterizer = NULL; + draw_set_rasterizer_state(llvmpipe->draw, NULL, handle); } llvmpipe->dirty |= LP_NEW_RASTERIZER; -- cgit v1.2.3 From 7f0dc5ea1bb330c6589125baf4017c51a14dce8e Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Fri, 29 Oct 2010 00:47:13 +0100 Subject: llvmpipe: Moved draw pipeline twoside function to llvm setup code --- src/gallium/drivers/llvmpipe/lp_context.h | 6 ++ src/gallium/drivers/llvmpipe/lp_state_derived.c | 14 +++- src/gallium/drivers/llvmpipe/lp_state_setup.c | 85 ++++++++++++++++++++++++- src/gallium/drivers/llvmpipe/lp_state_setup.h | 3 +- 4 files changed, 103 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index db09c95b27..2230d500d2 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -104,6 +104,12 @@ struct llvmpipe_context { /** Vertex format */ struct vertex_info vertex_info; + /** Which vertex shader output slot contains color */ + int color_slot; + + /** Which vertex shader output slot contains bcolor */ + int bcolor_slot; + /** Which vertex shader output slot contains point size */ int psize_slot; diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 0f5f7369e0..1c9f03a381 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -75,13 +75,25 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) vs_index = draw_find_shader_output(llvmpipe->draw, lpfs->info.base.input_semantic_name[i], lpfs->info.base.input_semantic_index[i]); - + if (lpfs->info.base.input_semantic_name[i]==TGSI_SEMANTIC_COLOR){ + llvmpipe->color_slot = vinfo->num_attribs; + } /* * Emit the requested fs attribute for all but position. */ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } + /* Figure out if we need bcolor as well. + */ + vs_index = draw_find_shader_output(llvmpipe->draw, + TGSI_SEMANTIC_BCOLOR, 0); + + if (vs_index > 0) { + llvmpipe->bcolor_slot = vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + } + /* Figure out if we need pointsize as well. */ vs_index = draw_find_shader_output(llvmpipe->draw, diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 2c8b8b9a92..8383494651 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -33,6 +33,7 @@ #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 /* for LLVMVerifyFunction */ #include "lp_perf.h" @@ -74,6 +75,14 @@ struct lp_setup_args LLVMValueRef dy01_ooa; LLVMValueRef dx20_ooa; LLVMValueRef dx01_ooa; + + /* For twoside calcs + */ + LLVMValueRef det; + LLVMValueRef sign; + LLVMValueRef bcolor_slot; + LLVMValueRef color_slot; + }; static LLVMTypeRef type4f(void) @@ -472,13 +481,78 @@ 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, + const struct lp_setup_variant_key *key) +{ + struct lp_build_if_state if_state; + + 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 facing = args->facing; + LLVMValueRef front_facing = LLVMBuildICmp(b, LLVMIntEQ, facing, LLVMConstInt(LLVMInt32Type(), 0, 0), ""); /** need i1 for loop 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 */ + a0_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx1, 1, ""), "v0a"); + a1_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx1, 1, ""), "v1a"); + a2_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx1, 1, ""), "v2a"); + + a0_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx2, 1, ""), "v0a"); + a1_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx2, 1, ""), "v1a"); + a2_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx2, 1, ""), "v2a"); + + LLVMBuildStore(b, a0_new, LLVMBuildGEP(b, args->v0, &idx1, 1, "")); + LLVMBuildStore(b, a1_new, LLVMBuildGEP(b, args->v1, &idx1, 1, "")); + LLVMBuildStore(b, a2_new, LLVMBuildGEP(b, args->v2, &idx1, 1, "")); + } + lp_build_endif(&if_state); + +} + + /** * Generate the runtime callable function for the coefficient calculation. * */ static struct lp_setup_variant * generate_setup_variant(struct llvmpipe_screen *screen, - struct lp_setup_variant_key *key) + struct lp_setup_variant_key *key, + struct llvmpipe_context *lp) { struct lp_setup_variant *variant = NULL; struct lp_setup_args args; @@ -555,6 +629,10 @@ 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); + } emit_tri_coef(builder, &variant->key, &args); lp_emit_emms(builder); @@ -605,6 +683,7 @@ lp_make_setup_variant_key(struct llvmpipe_context *lp, key->num_inputs = fs->info.base.num_inputs; key->flatshade_first = lp->rasterizer->flatshade_first; 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]); key->pad = 0; @@ -612,7 +691,7 @@ lp_make_setup_variant_key(struct llvmpipe_context *lp, 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) { - if (lp->rasterizer->flatshade) + if (lp->rasterizer->flatshade) key->inputs[i].interp = LP_INTERP_CONSTANT; else key->inputs[i].interp = LP_INTERP_LINEAR; @@ -702,7 +781,7 @@ llvmpipe_update_setup(struct llvmpipe_context *lp) cull_setup_variants(lp); } - variant = generate_setup_variant(screen, key); + variant = generate_setup_variant(screen, key, lp); insert_at_head(&lp->setup_variants_list, &variant->list_item_global); lp->nr_setup_variants++; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.h b/src/gallium/drivers/llvmpipe/lp_state_setup.h index b0c81baa75..4079fb71f6 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h @@ -18,7 +18,8 @@ struct lp_setup_variant_key { unsigned num_inputs:8; unsigned flatshade_first:1; unsigned pixel_center_half:1; - unsigned pad:7; + unsigned twoside:1; + unsigned pad:6; unsigned size:16; struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; }; -- cgit v1.2.3 From 315f8daab1598a4de709d469a559b5aa09107404 Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Thu, 4 Nov 2010 11:42:55 +0000 Subject: 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 +- src/gallium/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 2230d500d2..4515dbb0af 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 8383494651..7751b7d6c3 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 4079fb71f6..40fb8ef428 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 cd1a5b1980..375ceb2b94 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); } -- cgit v1.2.3 From e3f106b5fe36ad558b3971ba88802c5d80b007de Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Sat, 13 Nov 2010 21:39:50 +0000 Subject: llvmpipe: clean up polygon offset function in lp setup code --- src/gallium/drivers/llvmpipe/lp_state_setup.c | 60 +++++++-------------------- 1 file changed, 16 insertions(+), 44 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 7751b7d6c3..03b411a336 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -202,29 +202,16 @@ static LLVMValueRef vert_clamp(LLVMBuilderRef b, LLVMValueRef x, LLVMValueRef min, - LLVMValueRef max, - LLVMValueRef clamp_ptr) + LLVMValueRef max) { - 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,""); + LLVMValueRef clamp_value; + + clamp_value = LLVMBuildSelect(b, min_result, min, x, ""); + clamp_value = LLVMBuildSelect(b, max_result, max, x, ""); + + return clamp_value; } static void @@ -542,11 +529,11 @@ 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 dzdx0, dzdx, dzdy0, dzdy; + LLVMValueRef max, max_value; LLVMValueRef idx[2]; LLVMValueRef one = LLVMConstReal(LLVMFloatType(), 1.0); @@ -584,10 +571,6 @@ lp_do_offset_tri(LLVMBuilderRef b, 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)); @@ -598,26 +581,15 @@ lp_do_offset_tri(LLVMBuilderRef b, /* 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); + max_value = LLVMBuildSelect(b, max, dzdx, dzdy, "max"); - zoffset = LLVMBuildLoad(b, zoffset_ptr,""); + mult = LLVMBuildFMul(b, max_value, LLVMConstReal(LLVMFloatType(), key->scale), ""); + zoffset = LLVMBuildFAdd(b, LLVMConstReal(LLVMFloatType(), key->units), mult, "zoffset"); /* 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); + z0_new = vert_clamp(b, LLVMBuildFAdd(b, v0_z, zoffset, ""), zero, one); + z1_new = vert_clamp(b, LLVMBuildFAdd(b, v1_z, zoffset, ""), zero, one); + z2_new = vert_clamp(b, LLVMBuildFAdd(b, v2_z, zoffset, ""), zero, one); /* store back new offsetted z values */ idx[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); @@ -716,7 +688,7 @@ generate_setup_variant(struct llvmpipe_screen *screen, if (variant->key.twoside){ lp_twoside(builder, &args, &variant->key); } - if (variant->key.scale){ + if (variant->key.scale || variant->key.units){ lp_do_offset_tri(builder, &args, &variant->key); } emit_tri_coef(builder, &variant->key, &args); -- cgit v1.2.3 From d4b5cf6c05d4fcb0acaa36490f7d3379e7fb3c0e Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Fri, 19 Nov 2010 12:53:51 +0000 Subject: llvmpipe: fix such that offset/twoside function only does in-place modification --- src/gallium/drivers/llvmpipe/lp_state_setup.c | 314 +++++++++++++------------- 1 file changed, 159 insertions(+), 155 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 03b411a336..c3c2c8bd6d 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -76,7 +76,13 @@ struct lp_setup_args LLVMValueRef dy20_ooa; LLVMValueRef dy01_ooa; LLVMValueRef dx20_ooa; - LLVMValueRef dx01_ooa; + LLVMValueRef dx01_ooa; + + /* Temporary, per-attribute: + */ + LLVMValueRef v0a; + LLVMValueRef v1a; + LLVMValueRef v2a; }; static LLVMTypeRef type4f(void) @@ -152,16 +158,11 @@ static void emit_constant_coef4( LLVMBuilderRef builder, struct lp_setup_args *args, unsigned slot, - LLVMValueRef vert, - unsigned attr) + LLVMValueRef vert) { LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0); LLVMValueRef zerovec = vec4f_from_scalar(builder, zero, "zero"); - LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), attr, 0); - LLVMValueRef attr_ptr = LLVMBuildGEP(builder, vert, &idx, 1, "attr_ptr"); - LLVMValueRef vert_attr = LLVMBuildLoad(builder, attr_ptr, "vert_attr"); - - store_coef(builder, args, slot, vert_attr, zerovec, zerovec); + store_coef(builder, args, slot, vert, zerovec, zerovec); } @@ -214,6 +215,132 @@ vert_clamp(LLVMBuilderRef b, return clamp_value; } +static void +lp_twoside(LLVMBuilderRef b, + struct lp_setup_args *args, + const struct lp_setup_variant_key *key) +{ + LLVMValueRef a0_back, a1_back, a2_back; + 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 if condition */ + + a0_back = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx2, 1, ""), "v0a_back"); + a1_back = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx2, 1, ""), "v1a_back"); + a2_back = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx2, 1, ""), "v2a_back"); + + /* Possibly swap the front and back attrib values, + * + * Prefer select to if so we don't have to worry about phis or + * allocas. + */ + args->v0a = LLVMBuildSelect(b, front_facing, args->v0a, a0_back, ""); + args->v1a = LLVMBuildSelect(b, front_facing, args->v1a, a1_back, ""); + args->v2a = LLVMBuildSelect(b, front_facing, args->v2a, a2_back, ""); + +} + +static void +lp_do_offset_tri(LLVMBuilderRef b, + struct lp_setup_args *args, + const struct lp_setup_variant_key *key) +{ + struct lp_build_context bld; + LLVMValueRef zoffset, mult; + LLVMValueRef z0_new, z1_new, z2_new; + LLVMValueRef dzdx0, dzdx, dzdy0, dzdy; + LLVMValueRef max, max_value; + + 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"); + + /* 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, ""); + max_value = LLVMBuildSelect(b, max, dzdx, dzdy, "max"); + + mult = LLVMBuildFMul(b, max_value, LLVMConstReal(LLVMFloatType(), key->scale), ""); + zoffset = LLVMBuildFAdd(b, LLVMConstReal(LLVMFloatType(), key->units), mult, "zoffset"); + + /* clamp and do offset */ + z0_new = vert_clamp(b, LLVMBuildFAdd(b, v0_z, zoffset, ""), zero, one); + z1_new = vert_clamp(b, LLVMBuildFAdd(b, v1_z, zoffset, ""), zero, one); + z2_new = vert_clamp(b, LLVMBuildFAdd(b, v2_z, zoffset, ""), zero, one); + + /* insert into args->a0.z, a1.z, a2.z: + */ + args->v0a = LLVMBuildInsertElement(b, args->v0a, z0_new, LLVMConstInt(LLVMInt32Type(), 2, 0), ""); + args->v1a = LLVMBuildInsertElement(b, args->v1a, z1_new, LLVMConstInt(LLVMInt32Type(), 2, 0), ""); + args->v2a = LLVMBuildInsertElement(b, args->v2a, z2_new, LLVMConstInt(LLVMInt32Type(), 2, 0), ""); +} + +static void +load_attribute(LLVMBuilderRef b, + struct lp_setup_args *args, + const struct lp_setup_variant_key *key, + unsigned slot, + unsigned vert_attr) +{ + LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), vert_attr, 0); + + /* Load the vertex data + */ + args->v0a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx, 1, ""), "v0a"); + args->v1a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx, 1, ""), "v1a"); + args->v2a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx, 1, ""), "v2a"); + + + /* Potentially modify it according to twoside, offset, etc: + */ + if (slot == 0 && (key->scale != 0.0f || key->units != 0.0f)) { + lp_do_offset_tri(b, args, key); + } + + if (key->twoside && slot == key->color_slot) { + lp_twoside(b, args, key); + } +} + static void emit_coef4( LLVMBuilderRef b, struct lp_setup_args *args, @@ -260,20 +387,17 @@ emit_coef4( LLVMBuilderRef b, static void emit_linear_coef( LLVMBuilderRef b, struct lp_setup_args *args, - unsigned slot, - unsigned vert_attr) + unsigned slot) { - LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), vert_attr, 0); - - LLVMValueRef a0 = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx, 1, ""), "v0a"); - LLVMValueRef a1 = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx, 1, ""), "v1a"); - LLVMValueRef a2 = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx, 1, ""), "v2a"); - - emit_coef4(b, args, slot, a0, a1, a2); + /* nothing to do anymore */ + emit_coef4(b, + args, slot, + args->v0a, + args->v1a, + args->v2a); } - /** * Compute a0, dadx and dady for a perspective-corrected interpolant, * for a triangle. @@ -285,24 +409,17 @@ emit_linear_coef( LLVMBuilderRef b, static void emit_perspective_coef( LLVMBuilderRef b, struct lp_setup_args *args, - unsigned slot, - unsigned vert_attr) + unsigned slot) { /* premultiply by 1/w (v[0][3] is always 1/w): */ - LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), vert_attr, 0); - - LLVMValueRef v0a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx, 1, ""), "v0a"); - LLVMValueRef v1a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx, 1, ""), "v1a"); - LLVMValueRef v2a = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx, 1, ""), "v2a"); - LLVMValueRef v0_oow = vec4f_from_scalar(b, vert_attrib(b, args->v0, 0, 3, ""), "v0_oow"); LLVMValueRef v1_oow = vec4f_from_scalar(b, vert_attrib(b, args->v1, 0, 3, ""), "v1_oow"); LLVMValueRef v2_oow = vec4f_from_scalar(b, vert_attrib(b, args->v2, 0, 3, ""), "v2_oow"); - LLVMValueRef v0_oow_v0a = LLVMBuildFMul(b, v0a, v0_oow, "v0_oow_v0a"); - LLVMValueRef v1_oow_v1a = LLVMBuildFMul(b, v1a, v1_oow, "v1_oow_v1a"); - LLVMValueRef v2_oow_v2a = LLVMBuildFMul(b, v2a, v2_oow, "v2_oow_v2a"); + LLVMValueRef v0_oow_v0a = LLVMBuildFMul(b, args->v0a, v0_oow, "v0_oow_v0a"); + LLVMValueRef v1_oow_v1a = LLVMBuildFMul(b, args->v1a, v1_oow, "v1_oow_v1a"); + LLVMValueRef v2_oow_v2a = LLVMBuildFMul(b, args->v2a, v2_oow, "v2_oow_v2a"); emit_coef4(b, args, slot, v0_oow_v0a, v1_oow_v1a, v2_oow_v2a); } @@ -311,9 +428,9 @@ emit_perspective_coef( LLVMBuilderRef b, static void emit_position_coef( LLVMBuilderRef builder, struct lp_setup_args *args, - int slot, int attrib ) + int slot ) { - emit_linear_coef(builder, args, slot, attrib); + emit_linear_coef(builder, args, slot); } @@ -331,29 +448,34 @@ emit_tri_coef( LLVMBuilderRef builder, /* The internal position input is in slot zero: */ - emit_position_coef(builder, args, 0, 0); + load_attribute(builder, args, key, 0, 0); + emit_position_coef(builder, args, 0); /* setup interpolation for all the remaining attributes: */ for (slot = 0; slot < key->num_inputs; slot++) { - unsigned vert_attr = key->inputs[slot].src_index; + + if (key->inputs[slot].interp == LP_INTERP_CONSTANT || + key->inputs[slot].interp == LP_INTERP_LINEAR || + key->inputs[slot].interp == LP_INTERP_PERSPECTIVE) + load_attribute(builder, args, key, slot, key->inputs[slot].src_index); switch (key->inputs[slot].interp) { case LP_INTERP_CONSTANT: if (key->flatshade_first) { - emit_constant_coef4(builder, args, slot+1, args->v0, vert_attr); + emit_constant_coef4(builder, args, slot+1, args->v0a); } else { - emit_constant_coef4(builder, args, slot+1, args->v2, vert_attr); + emit_constant_coef4(builder, args, slot+1, args->v2a); } break; case LP_INTERP_LINEAR: - emit_linear_coef(builder, args, slot+1, vert_attr); + emit_linear_coef(builder, args, slot+1); break; case LP_INTERP_PERSPECTIVE: - emit_perspective_coef(builder, args, slot+1, vert_attr); + emit_perspective_coef(builder, args, slot+1); break; case LP_INTERP_POSITION: @@ -489,118 +611,6 @@ init_args(LLVMBuilderRef b, args->y0_center = vec4f_from_scalar(b, y0_center, "y0_center_4f"); } -static void -lp_twoside(LLVMBuilderRef b, - struct lp_setup_args *args, - const struct lp_setup_variant_key *key) -{ - struct lp_build_if_state if_state; - - LLVMValueRef a0_old, a1_old, a2_old; - LLVMValueRef a0_new, a1_new, a2_new; - - 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 if condition */ - - lp_build_if(&if_state, b, front_facing); - { - /* swap the front and back attrib values */ - a0_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx1, 1, ""), "v0a"); - a1_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx1, 1, ""), "v1a"); - a2_old = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx1, 1, ""), "v2a"); - - a0_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v0, &idx2, 1, ""), "v0a"); - a1_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v1, &idx2, 1, ""), "v1a"); - a2_new = LLVMBuildLoad(b, LLVMBuildGEP(b, args->v2, &idx2, 1, ""), "v2a"); - - LLVMBuildStore(b, a0_new, LLVMBuildGEP(b, args->v0, &idx1, 1, "")); - LLVMBuildStore(b, a1_new, LLVMBuildGEP(b, args->v1, &idx1, 1, "")); - LLVMBuildStore(b, a2_new, LLVMBuildGEP(b, args->v2, &idx1, 1, "")); - } - lp_build_endif(&if_state); - -} - -static void -lp_do_offset_tri(LLVMBuilderRef b, - struct lp_setup_args *args, - const struct lp_setup_variant_key *key) -{ - struct lp_build_context bld; - LLVMValueRef zoffset, mult; - LLVMValueRef z0_new, z1_new, z2_new; - LLVMValueRef dzdx0, dzdx, dzdy0, dzdy; - LLVMValueRef max, max_value; - - 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"); - - /* 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, ""); - max_value = LLVMBuildSelect(b, max, dzdx, dzdy, "max"); - - mult = LLVMBuildFMul(b, max_value, LLVMConstReal(LLVMFloatType(), key->scale), ""); - zoffset = LLVMBuildFAdd(b, LLVMConstReal(LLVMFloatType(), key->units), mult, "zoffset"); - - /* clamp and do offset */ - z0_new = vert_clamp(b, LLVMBuildFAdd(b, v0_z, zoffset, ""), zero, one); - z1_new = vert_clamp(b, LLVMBuildFAdd(b, v1_z, zoffset, ""), zero, one); - z2_new = vert_clamp(b, LLVMBuildFAdd(b, v2_z, zoffset, ""), zero, one); - - /* 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. * @@ -685,12 +695,6 @@ 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){ - lp_twoside(builder, &args, &variant->key); - } - if (variant->key.scale || variant->key.units){ - lp_do_offset_tri(builder, &args, &variant->key); - } emit_tri_coef(builder, &variant->key, &args); lp_emit_emms(builder); -- cgit v1.2.3 From 081ce2680eb94f4f322faa26800a3906db6e2571 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 19 Nov 2010 16:16:30 +0000 Subject: llvmpipe: fix up twoside after recent changes Fix my slot/attr confusion. --- src/gallium/drivers/llvmpipe/lp_state_setup.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index c3c2c8bd6d..129ec0af3d 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -235,9 +235,9 @@ lp_twoside(LLVMBuilderRef b, * Prefer select to if so we don't have to worry about phis or * allocas. */ - args->v0a = LLVMBuildSelect(b, front_facing, args->v0a, a0_back, ""); - args->v1a = LLVMBuildSelect(b, front_facing, args->v1a, a1_back, ""); - args->v2a = LLVMBuildSelect(b, front_facing, args->v2a, a2_back, ""); + args->v0a = LLVMBuildSelect(b, front_facing, a0_back, args->v0a, ""); + args->v1a = LLVMBuildSelect(b, front_facing, a1_back, args->v1a, ""); + args->v2a = LLVMBuildSelect(b, front_facing, a2_back, args->v2a, ""); } @@ -318,7 +318,6 @@ static void load_attribute(LLVMBuilderRef b, struct lp_setup_args *args, const struct lp_setup_variant_key *key, - unsigned slot, unsigned vert_attr) { LLVMValueRef idx = LLVMConstInt(LLVMInt32Type(), vert_attr, 0); @@ -332,11 +331,11 @@ load_attribute(LLVMBuilderRef b, /* Potentially modify it according to twoside, offset, etc: */ - if (slot == 0 && (key->scale != 0.0f || key->units != 0.0f)) { + if (vert_attr == 0 && (key->scale != 0.0f || key->units != 0.0f)) { lp_do_offset_tri(b, args, key); } - if (key->twoside && slot == key->color_slot) { + if (key->twoside && vert_attr == key->color_slot) { lp_twoside(b, args, key); } } @@ -448,7 +447,7 @@ emit_tri_coef( LLVMBuilderRef builder, /* The internal position input is in slot zero: */ - load_attribute(builder, args, key, 0, 0); + load_attribute(builder, args, key, 0); emit_position_coef(builder, args, 0); /* setup interpolation for all the remaining attributes: @@ -458,7 +457,7 @@ emit_tri_coef( LLVMBuilderRef builder, if (key->inputs[slot].interp == LP_INTERP_CONSTANT || key->inputs[slot].interp == LP_INTERP_LINEAR || key->inputs[slot].interp == LP_INTERP_PERSPECTIVE) - load_attribute(builder, args, key, slot, key->inputs[slot].src_index); + load_attribute(builder, args, key, key->inputs[slot].src_index); switch (key->inputs[slot].interp) { case LP_INTERP_CONSTANT: -- cgit v1.2.3 From 546c5ffa11d70631348e5776df7a4168f07600f6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 19 Nov 2010 16:17:36 +0000 Subject: llvmpipe: twoside for specular color also --- src/gallium/drivers/llvmpipe/lp_context.h | 4 ++-- src/gallium/drivers/llvmpipe/lp_state_derived.c | 26 ++++++++++++++++++------- src/gallium/drivers/llvmpipe/lp_state_setup.c | 20 ++++++++++++------- src/gallium/drivers/llvmpipe/lp_state_setup.h | 12 ++++++++---- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 4515dbb0af..a35e09e8b4 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -105,10 +105,10 @@ struct llvmpipe_context { struct vertex_info vertex_info; /** Which vertex shader output slot contains color */ - int color_slot; + int color_slot[2]; /** Which vertex shader output slot contains bcolor */ - int bcolor_slot; + int bcolor_slot[2]; /** Which vertex shader output slot contains point size */ int psize_slot; diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 1c9f03a381..8725ea39fe 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -53,6 +53,11 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) unsigned vs_index; uint i; + llvmpipe->color_slot[0] = ~0; + llvmpipe->color_slot[1] = ~0; + llvmpipe->bcolor_slot[0] = ~0; + llvmpipe->bcolor_slot[1] = ~0; + /* * Match FS inputs against VS outputs, emitting the necessary * attributes. Could cache these structs and look them up with a @@ -75,9 +80,13 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) vs_index = draw_find_shader_output(llvmpipe->draw, lpfs->info.base.input_semantic_name[i], lpfs->info.base.input_semantic_index[i]); - if (lpfs->info.base.input_semantic_name[i]==TGSI_SEMANTIC_COLOR){ - llvmpipe->color_slot = vinfo->num_attribs; + + if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR && + lpfs->info.base.input_semantic_index[i] < 2) { + int idx = lpfs->info.base.input_semantic_index[i]; + llvmpipe->color_slot[idx] = vinfo->num_attribs; } + /* * Emit the requested fs attribute for all but position. */ @@ -86,14 +95,17 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) /* Figure out if we need bcolor as well. */ - vs_index = draw_find_shader_output(llvmpipe->draw, - TGSI_SEMANTIC_BCOLOR, 0); + for (i = 0; i < 2; i++) { + vs_index = draw_find_shader_output(llvmpipe->draw, + TGSI_SEMANTIC_BCOLOR, i); - if (vs_index > 0) { - llvmpipe->bcolor_slot = vinfo->num_attribs; - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + if (vs_index > 0) { + llvmpipe->bcolor_slot[i] = vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); + } } + /* Figure out if we need pointsize as well. */ vs_index = draw_find_shader_output(llvmpipe->draw, diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 129ec0af3d..194b014436 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -218,10 +218,11 @@ vert_clamp(LLVMBuilderRef b, static void lp_twoside(LLVMBuilderRef b, struct lp_setup_args *args, - const struct lp_setup_variant_key *key) + const struct lp_setup_variant_key *key, + int bcolor_slot) { LLVMValueRef a0_back, a1_back, a2_back; - LLVMValueRef idx2 = LLVMConstInt(LLVMInt32Type(), key->bcolor_slot, 0); + LLVMValueRef idx2 = LLVMConstInt(LLVMInt32Type(), bcolor_slot, 0); LLVMValueRef facing = args->facing; LLVMValueRef front_facing = LLVMBuildICmp(b, LLVMIntEQ, facing, LLVMConstInt(LLVMInt32Type(), 0, 0), ""); /** need i1 for if condition */ @@ -335,8 +336,11 @@ load_attribute(LLVMBuilderRef b, lp_do_offset_tri(b, args, key); } - if (key->twoside && vert_attr == key->color_slot) { - lp_twoside(b, args, key); + if (key->twoside) { + if (vert_attr == key->color_slot && key->bcolor_slot != ~0) + lp_twoside(b, args, key, key->bcolor_slot); + else if (vert_attr == key->spec_slot && key->bspec_slot != ~0) + lp_twoside(b, args, key, key->bspec_slot); } } @@ -746,9 +750,11 @@ 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]); - key->color_slot = lp->color_slot; - key->bcolor_slot = lp->bcolor_slot; + inputs[key->num_inputs]); + key->color_slot = lp->color_slot[0]; + key->bcolor_slot = lp->bcolor_slot[0]; + key->spec_slot = lp->color_slot[1]; + key->bspec_slot = lp->bcolor_slot[1]; key->units = (float) (lp->rasterizer->offset_units * lp->mrd); key->scale = lp->rasterizer->offset_scale; key->pad = 0; diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.h b/src/gallium/drivers/llvmpipe/lp_state_setup.h index 40fb8ef428..90c55ca4ce 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h @@ -15,14 +15,18 @@ struct lp_setup_variant_list_item struct lp_setup_variant_key { + unsigned size:16; unsigned num_inputs:8; + unsigned color_slot:8; + + unsigned bcolor_slot:8; + unsigned spec_slot:8; + unsigned bspec_slot:8; unsigned flatshade_first:1; unsigned pixel_center_half:1; unsigned twoside:1; - unsigned color_slot:8; - unsigned bcolor_slot:8; - unsigned size:16; - unsigned pad:21; + unsigned pad:5; + float units; float scale; struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; -- cgit v1.2.3