diff options
author | Keith Whitwell <keithw@vmware.com> | 2010-11-22 10:36:01 +0000 |
---|---|---|
committer | Keith Whitwell <keithw@vmware.com> | 2010-11-22 10:36:01 +0000 |
commit | b2ddb93ff3b8c88682634ccdef247967e31fab84 (patch) | |
tree | 495da09bbeddd9fdb51e4301c113bcf4ae94c8e4 /src/gallium/drivers/llvmpipe | |
parent | d5aadf0d80e8c973ef5cf9d82e97f23f0e3c032b (diff) | |
parent | 546c5ffa11d70631348e5776df7a4168f07600f6 (diff) |
Merge branch 'lp-offset-twoside'
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_context.h | 9 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_derived.c | 24 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_rasterizer.c | 99 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_setup.c | 229 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_setup.h | 13 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_surface.c | 1 |
6 files changed, 306 insertions, 69 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index db09c95b27..a35e09e8b4 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -104,9 +104,18 @@ struct llvmpipe_context { /** Vertex format */ struct vertex_info vertex_info; + /** Which vertex shader output slot contains color */ + int color_slot[2]; + + /** Which vertex shader output slot contains bcolor */ + int bcolor_slot[2]; + /** 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_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 0f5f7369e0..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 @@ -76,12 +81,31 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) 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 && + 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. */ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } + /* Figure out if we need bcolor as well. + */ + 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[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_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; diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 2c8b8b9a92..194b014436 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -30,9 +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 <llvm-c/Analysis.h> /* for LLVMVerifyFunction */ #include "lp_perf.h" @@ -74,6 +77,12 @@ struct lp_setup_args LLVMValueRef dy01_ooa; LLVMValueRef dx20_ooa; LLVMValueRef dx01_ooa; + + /* Temporary, per-attribute: + */ + LLVMValueRef v0a; + LLVMValueRef v1a; + LLVMValueRef v2a; }; static LLVMTypeRef type4f(void) @@ -149,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); } @@ -195,7 +199,150 @@ 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 min_result = LLVMBuildFCmp(b, LLVMRealUGT, min, x, ""); + LLVMValueRef max_result = LLVMBuildFCmp(b, LLVMRealUGT, x, max, ""); + LLVMValueRef clamp_value; + + clamp_value = LLVMBuildSelect(b, min_result, min, x, ""); + clamp_value = LLVMBuildSelect(b, max_result, max, x, ""); + + return clamp_value; +} + +static void +lp_twoside(LLVMBuilderRef b, + struct lp_setup_args *args, + const struct lp_setup_variant_key *key, + int bcolor_slot) +{ + LLVMValueRef a0_back, a1_back, a2_back; + 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 */ + + 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, a0_back, args->v0a, ""); + args->v1a = LLVMBuildSelect(b, front_facing, a1_back, args->v1a, ""); + args->v2a = LLVMBuildSelect(b, front_facing, a2_back, args->v2a, ""); + +} +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 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 (vert_attr == 0 && (key->scale != 0.0f || key->units != 0.0f)) { + lp_do_offset_tri(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); + } +} static void emit_coef4( LLVMBuilderRef b, @@ -243,20 +390,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. @@ -268,24 +412,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); } @@ -294,9 +431,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); } @@ -314,29 +451,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); + 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, 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: @@ -478,7 +620,8 @@ init_args(LLVMBuilderRef b, */ 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; @@ -605,14 +748,20 @@ 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->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; - 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 +851,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..90c55ca4ce 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h @@ -15,11 +15,20 @@ 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 pad:7; - unsigned size:16; + unsigned twoside:1; + unsigned pad:5; + + 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); } |