/* Build the actual shader */
lp_build_tgsi_soa(gallivm, tokens, type, &mask,
- consts_ptr, interp->pos, interp->inputs,
+ consts_ptr, NULL, /* sys values array */
+ interp->pos, interp->inputs,
outputs, sampler, &shader->info.base);
/* Alpha test */
struct lp_type fs_type;
struct lp_type blend_type;
LLVMTypeRef fs_elem_type;
- LLVMTypeRef fs_int_vec_type;
LLVMTypeRef blend_vec_type;
LLVMTypeRef arg_types[11];
LLVMTypeRef func_type;
unsigned i;
unsigned chan;
unsigned cbuf;
+ boolean cbuf0_write_all;
/* Adjust color input interpolation according to flatshade state:
*/
}
}
+ /* check if writes to cbuf[0] are to be copied to all cbufs */
+ cbuf0_write_all = FALSE;
+ for (i = 0;i < shader->info.base.num_properties; i++) {
+ if (shader->info.base.properties[i].name ==
+ TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS) {
+ cbuf0_write_all = TRUE;
+ break;
+ }
+ }
/* TODO: actually pick these based on the fs and color buffer
* characteristics. */
*/
fs_elem_type = lp_build_elem_type(gallivm, fs_type);
- fs_int_vec_type = lp_build_int_vec_type(gallivm, fs_type);
blend_vec_type = lp_build_vec_type(gallivm, blend_type);
mask_input,
counter);
- for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++)
- for(chan = 0; chan < NUM_CHANNELS; ++chan)
- fs_out_color[cbuf][chan][i] = out_color[cbuf][chan];
+ for (cbuf = 0; cbuf < key->nr_cbufs; cbuf++)
+ for (chan = 0; chan < NUM_CHANNELS; ++chan)
+ fs_out_color[cbuf][chan][i] =
+ out_color[cbuf * !cbuf0_write_all][chan];
}
sampler->destroy(sampler);
LLVMWriteBitcodeToFile(gallivm->module, "llvmpipe.bc");
}
+ variant->nr_instrs += lp_build_count_instructions(function);
/*
* Translate the LLVM IR into machine code.
*/
case TGSI_INTERPOLATE_PERSPECTIVE:
shader->inputs[i].interp = LP_INTERP_PERSPECTIVE;
break;
+ case TGSI_INTERPOLATE_COLOR:
+ shader->inputs[i].interp = LP_INTERP_COLOR;
+ break;
default:
assert(0);
break;
}
switch (shader->info.base.input_semantic_name[i]) {
- case TGSI_SEMANTIC_COLOR:
- /* Colors may be either linearly or constant interpolated in
- * the fragment shader, but that information isn't available
- * here. Mark color inputs and fix them up later.
- */
- shader->inputs[i].interp = LP_INTERP_COLOR;
- break;
case TGSI_SEMANTIC_FACE:
shader->inputs[i].interp = LP_INTERP_FACING;
break;
/* remove from context's list */
remove_from_list(&variant->list_item_global);
lp->nr_fs_variants--;
+ lp->nr_fs_instrs -= variant->nr_instrs;
FREE(variant);
}
*
* Also, force rgb/alpha func/factors match, to make AoS blending easier.
*/
- if (format_desc->swizzle[3] > UTIL_FORMAT_SWIZZLE_W) {
+ if (format_desc->swizzle[3] > UTIL_FORMAT_SWIZZLE_W ||
+ format_desc->swizzle[3] == format_desc->swizzle[0]) {
blend_rt->rgb_src_factor = force_dst_alpha_one(blend_rt->rgb_src_factor);
blend_rt->rgb_dst_factor = force_dst_alpha_one(blend_rt->rgb_dst_factor);
blend_rt->alpha_func = blend_rt->rgb_func;
/* variant not found, create it now */
int64_t t0, t1, dt;
unsigned i;
+ unsigned variants_to_cull;
+
+ if (0) {
+ debug_printf("%u variants,\t%u instrs,\t%u instrs/variant\n",
+ lp->nr_fs_variants,
+ lp->nr_fs_instrs,
+ lp->nr_fs_variants ? lp->nr_fs_instrs / lp->nr_fs_variants : 0);
+ }
/* First, check if we've exceeded the max number of shader variants.
* If so, free 25% of them (the least recently used ones).
*/
- if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
+ variants_to_cull = lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS ? LP_MAX_SHADER_VARIANTS / 4 : 0;
+
+ if (variants_to_cull ||
+ lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS) {
struct pipe_context *pipe = &lp->pipe;
/*
*/
llvmpipe_finish(pipe, __FUNCTION__);
- for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) {
+ /*
+ * We need to re-check lp->nr_fs_variants because an arbitrarliy large
+ * number of shader variants (potentially all of them) could be
+ * pending for destruction on flush.
+ */
+
+ for (i = 0; i < variants_to_cull || lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS; i++) {
struct lp_fs_variant_list_item *item;
+ if (is_empty_list(&lp->fs_variants_list)) {
+ break;
+ }
item = last_elem(&lp->fs_variants_list);
+ assert(item);
+ assert(item->base);
llvmpipe_remove_shader_variant(lp, item->base);
}
}
insert_at_head(&shader->variants, &variant->list_item_local);
insert_at_head(&lp->fs_variants_list, &variant->list_item_global);
lp->nr_fs_variants++;
+ lp->nr_fs_instrs += variant->nr_instrs;
shader->variants_cached++;
}
}