static struct lp_fragment_shader_variant * generate_variant(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, const struct lp_fragment_shader_variant_key *key) { struct lp_fragment_shader_variant *variant; boolean fullcolormask; variant = CALLOC_STRUCT(lp_fragment_shader_variant); if(!variant) return NULL; variant->shader = shader; variant->list_item_global.base = variant; variant->list_item_local.base = variant; variant->no = shader->variants_created++; memcpy(&variant->key, key, shader->variant_key_size); /* * Determine whether we are touching all channels in the color buffer. */ fullcolormask = FALSE; if (key->nr_cbufs == 1) { const struct util_format_description *format_desc; format_desc = util_format_description(key->cbuf_format[0]); if ((~key->blend.rt[0].colormask & util_format_colormask(format_desc)) == 0) { fullcolormask = TRUE; } } variant->opaque = !key->blend.logicop_enable && !key->blend.rt[0].blend_enable && fullcolormask && !key->stencil[0].enabled && !key->alpha.enabled && !key->depth.enabled && !shader->info.uses_kill ? TRUE : FALSE; if (gallivm_debug & GALLIVM_DEBUG_IR) { lp_debug_fs_variant(variant); } generate_fragment(lp, shader, variant, RAST_EDGE_TEST); if (variant->opaque) { /* Specialized shader, which doesn't need to read the color buffer. */ generate_fragment(lp, shader, variant, RAST_WHOLE); } else { variant->jit_function[RAST_WHOLE] = variant->jit_function[RAST_EDGE_TEST]; } return variant; }
char* gt_shredder_shred(GtShredder *shredder, unsigned long *fragment_length, GtStr *desc) { char *frag; gt_assert(shredder && fragment_length); while ((frag = generate_fragment(shredder, fragment_length, desc))) { if (shredder->sample_probability == 1.0 || gt_rand_0_to_1() <= shredder->sample_probability) { return frag; } else gt_free(frag); } return NULL; }
void llvmpipe_update_fs(struct llvmpipe_context *lp) { struct lp_fragment_shader *shader = lp->fs; struct lp_fragment_shader_variant_key key; struct lp_fragment_shader_variant *variant; make_variant_key(lp, shader, &key); variant = shader->variants; while(variant) { if(memcmp(&variant->key, &key, sizeof key) == 0) break; variant = variant->next; } if(!variant) variant = generate_fragment(lp, shader, &key); shader->current = variant; }
static struct lp_fragment_shader_variant * generate_variant(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, const struct lp_fragment_shader_variant_key *key) { struct lp_fragment_shader_variant *variant; if (LP_DEBUG & DEBUG_JIT) { unsigned i; tgsi_dump(shader->base.tokens, 0); if(key->depth.enabled) { debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format)); debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE)); debug_printf("depth.writemask = %u\n", key->depth.writemask); } if(key->alpha.enabled) { debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE)); debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); } if(key->blend.logicop_enable) { debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); } else if(key->blend.rt[0].blend_enable) { debug_printf("blend.rgb_func = %s\n", util_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); debug_printf("rgb_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); debug_printf("rgb_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); debug_printf("alpha_func = %s\n", util_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); debug_printf("alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); debug_printf("alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); } debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { if(key->sampler[i].format) { debug_printf("sampler[%u] = \n", i); debug_printf(" .format = %s\n", util_format_name(key->sampler[i].format)); debug_printf(" .target = %s\n", util_dump_tex_target(key->sampler[i].target, TRUE)); debug_printf(" .pot = %u %u %u\n", key->sampler[i].pot_width, key->sampler[i].pot_height, key->sampler[i].pot_depth); debug_printf(" .wrap = %s %s %s\n", util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); debug_printf(" .min_img_filter = %s\n", util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); debug_printf(" .min_mip_filter = %s\n", util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); debug_printf(" .mag_img_filter = %s\n", util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); if(key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) debug_printf(" .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE)); debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); } } } variant = CALLOC_STRUCT(lp_fragment_shader_variant); if(!variant) return NULL; variant->shader = shader; memcpy(&variant->key, key, sizeof *key); generate_fragment(lp, shader, variant, 0); generate_fragment(lp, shader, variant, 1); /* insert new variant into linked list */ variant->next = shader->variants; shader->variants = variant; return variant; }