llvmpipe: Don't waste time interpolating unused input channels.
This commit is contained in:
@@ -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 );
|
||||
for (attrib = 0; attrib < info->num_inputs; ++attrib) {
|
||||
bld->mask[1 + attrib] = info->input_usage_mask[attrib];
|
||||
|
||||
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;
|
||||
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];
|
||||
|
||||
first = decl->Range.First;
|
||||
last = decl->Range.Last;
|
||||
mask = decl->Declaration.UsageMask;
|
||||
}
|
||||
bld->num_attribs = 1 + info->num_inputs;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bld->num_attribs = MAX2(bld->num_attribs, 1 + last + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_TOKEN_TYPE_INSTRUCTION:
|
||||
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
||||
case TGSI_TOKEN_TYPE_PROPERTY:
|
||||
break;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user