#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"
*/
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,
LLVMValueRef x0,
LLVMValueRef y0)
{
- struct tgsi_parse_context parse;
- struct tgsi_full_declaration *decl;
+ unsigned attrib;
+ unsigned chan;
memset(bld, 0, sizeof *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);
struct tgsi_token;
+struct tgsi_shader_info;
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,
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.
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;
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:
/* 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;
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,
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;