From: José Fonseca Date: Tue, 1 Jun 2010 15:28:45 +0000 (+0100) Subject: llvmpipe: Don't waste time interpolating unused input channels. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=149cb7682e37ce719d693f120e68dde60ba73bdf;p=mesa.git llvmpipe: Don't waste time interpolating unused input channels. --- diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c index 838691e14b0..07c9e646630 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c @@ -37,7 +37,7 @@ #include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_math.h" -#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" #include "gallivm/lp_bld_debug.h" #include "gallivm/lp_bld_const.h" #include "gallivm/lp_bld_arit.h" @@ -315,7 +315,7 @@ pos_update(struct lp_build_interp_soa_context *bld, int quad_index) */ void lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, - const struct tgsi_token *tokens, + const struct tgsi_shader_info *info, boolean flatshade, LLVMBuilderRef builder, struct lp_type type, @@ -325,8 +325,8 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, LLVMValueRef x0, LLVMValueRef y0) { - struct tgsi_parse_context parse; - struct tgsi_full_declaration *decl; + unsigned attrib; + unsigned chan; memset(bld, 0, sizeof *bld); @@ -342,48 +342,24 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, bld->interp[0] = TGSI_INTERPOLATE_LINEAR; /* Inputs */ - tgsi_parse_init( &parse, tokens ); - while( !tgsi_parse_end_of_tokens( &parse ) ) { - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - decl = &parse.FullToken.FullDeclaration; - if( decl->Declaration.File == TGSI_FILE_INPUT ) { - unsigned first, last, mask; - unsigned attrib; - - first = decl->Range.First; - last = decl->Range.Last; - mask = decl->Declaration.UsageMask; - - for( attrib = first; attrib <= last; ++attrib ) { - bld->mask[1 + attrib] = mask; - - /* XXX: have mesa set INTERP_CONSTANT in the fragment - * shader. - */ - if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR && - flatshade) - bld->interp[1 + attrib] = TGSI_INTERPOLATE_CONSTANT; - else - bld->interp[1 + attrib] = decl->Declaration.Interpolate; - } + for (attrib = 0; attrib < info->num_inputs; ++attrib) { + bld->mask[1 + attrib] = info->input_usage_mask[attrib]; - bld->num_attribs = MAX2(bld->num_attribs, 1 + last + 1); - } - break; + if (info->input_semantic_name[attrib] == TGSI_SEMANTIC_COLOR && + flatshade) + bld->interp[1 + attrib] = TGSI_INTERPOLATE_CONSTANT; + else + bld->interp[1 + attrib] = info->input_interpolate[attrib]; - case TGSI_TOKEN_TYPE_INSTRUCTION: - case TGSI_TOKEN_TYPE_IMMEDIATE: - case TGSI_TOKEN_TYPE_PROPERTY: - break; + } + bld->num_attribs = 1 + info->num_inputs; - default: - assert( 0 ); + /* Ensure all masked out input channels have a valid value */ + for (attrib = 0; attrib < bld->num_attribs; ++attrib) { + for (chan = 0; chan < NUM_CHANNELS; ++chan) { + bld->attribs[attrib][chan] = bld->base.undef; } } - tgsi_parse_free( &parse ); coeffs_init(bld, a0_ptr, dadx_ptr, dady_ptr); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h index 99a432957ce..2d41fefd47b 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h @@ -49,6 +49,7 @@ struct tgsi_token; +struct tgsi_shader_info; struct lp_build_interp_soa_context @@ -78,7 +79,7 @@ struct lp_build_interp_soa_context void lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, - const struct tgsi_token *tokens, + const struct tgsi_shader_info *info, boolean flatshade, LLVMBuilderRef builder, struct lp_type type, diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 719cf98454f..6a0dc551290 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -41,8 +41,11 @@ enum lp_interp { LP_INTERP_FACING }; -/* Describes how to generate all the fragment shader inputs from the - * the vertices passed into our triangle/line/point functions. + +/** + * Describes how to compute the interpolation coefficients (a0, dadx, dady) + * from the vertices passed into our triangle/line/point functions by the + * draw module. * * Vertices are treated as an array of float[4] values, indexed by * src_index. @@ -50,6 +53,7 @@ enum lp_interp { struct lp_shader_input { enum lp_interp interp; /* how to interpolate values */ unsigned src_index; /* where to find values in incoming vertices */ + unsigned usage_mask; /* bitmask of TGSI_WRITEMASK_x flags */ }; struct pipe_resource; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 0fc4dd665e8..b5600615420 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -208,22 +208,26 @@ static void setup_tri_coefficients( struct lp_setup_context *setup, case LP_INTERP_CONSTANT: if (setup->flatshade_first) { for (i = 0; i < NUM_CHANNELS; i++) - constant_coef(setup, tri, slot+1, v1[vert_attr][i], i); + if (setup->fs.input[slot].usage_mask & (1 << i)) + constant_coef(setup, tri, slot+1, v1[vert_attr][i], i); } else { for (i = 0; i < NUM_CHANNELS; i++) - constant_coef(setup, tri, slot+1, v3[vert_attr][i], i); + if (setup->fs.input[slot].usage_mask & (1 << i)) + constant_coef(setup, tri, slot+1, v3[vert_attr][i], i); } break; case LP_INTERP_LINEAR: for (i = 0; i < NUM_CHANNELS; i++) - linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); + if (setup->fs.input[slot].usage_mask & (1 << i)) + linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); break; case LP_INTERP_PERSPECTIVE: for (i = 0; i < NUM_CHANNELS; i++) - perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); + if (setup->fs.input[slot].usage_mask & (1 << i)) + perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); break; case LP_INTERP_POSITION: diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 2edfcb28ce6..773aadc92d9 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -77,6 +77,7 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) /* This can be pre-computed, except for flatshade: */ + inputs[i].usage_mask = lpfs->info.input_usage_mask[i]; switch (lpfs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_FACE: inputs[i].interp = LP_INTERP_FACING; diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 21e90fe00ec..d3f2eb2421e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -760,7 +760,7 @@ generate_fragment(struct llvmpipe_context *lp, generate_pos0(builder, x, y, &x0, &y0); lp_build_interp_soa_init(&interp, - shader->base.tokens, + &shader->info, key->flatshade, builder, fs_type, a0_ptr, dadx_ptr, dady_ptr, @@ -1013,8 +1013,20 @@ llvmpipe_create_fs_state(struct pipe_context *pipe, shader->base.tokens = tgsi_dup_tokens(templ->tokens); if (LP_DEBUG & DEBUG_TGSI) { + unsigned attrib; debug_printf("llvmpipe: Create fragment shader %p:\n", (void *) shader); tgsi_dump(templ->tokens, 0); + debug_printf("usage masks:\n"); + for (attrib = 0; attrib < shader->info.num_inputs; ++attrib) { + unsigned usage_mask = shader->info.input_usage_mask[attrib]; + debug_printf(" IN[%u].%s%s%s%s\n", + attrib, + usage_mask & TGSI_WRITEMASK_X ? "x" : "", + usage_mask & TGSI_WRITEMASK_Y ? "y" : "", + usage_mask & TGSI_WRITEMASK_Z ? "z" : "", + usage_mask & TGSI_WRITEMASK_W ? "w" : ""); + } + debug_printf("\n"); } return shader;