/** * We need to generate several variants of the fragment pipeline to match * all the combinations of the contributing state atoms. * * TODO: there is actually no reason to tie this to context state -- the * generated code could be cached globally in the screen. */ static void make_variant_key(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, struct lp_fragment_shader_variant_key *key) { unsigned i; memset(key, 0, sizeof *key); if(lp->framebuffer.zsbuf && lp->depth_stencil->depth.enabled) { key->zsbuf_format = lp->framebuffer.zsbuf->format; memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth); } key->alpha.enabled = lp->depth_stencil->alpha.enabled; if(key->alpha.enabled) key->alpha.func = lp->depth_stencil->alpha.func; /* alpha.ref_value is passed in jit_context */ key->flatshade = lp->rasterizer->flatshade; key->scissor = lp->rasterizer->scissor; if (lp->framebuffer.nr_cbufs) { memcpy(&key->blend, lp->blend, sizeof key->blend); } key->nr_cbufs = lp->framebuffer.nr_cbufs; for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { const struct util_format_description *format_desc; unsigned chan; format_desc = util_format_description(lp->framebuffer.cbufs[i]->format); assert(format_desc->layout == UTIL_FORMAT_COLORSPACE_RGB || format_desc->layout == UTIL_FORMAT_COLORSPACE_SRGB); /* mask out color channels not present in the color buffer. * Should be simple to incorporate per-cbuf writemasks: */ for(chan = 0; chan < 4; ++chan) { enum util_format_swizzle swizzle = format_desc->swizzle[chan]; if(swizzle <= UTIL_FORMAT_SWIZZLE_W) key->blend.rt[0].colormask |= (1 << chan); } } for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]); }
/** * We need to generate several variants of the fragment pipeline to match * all the combinations of the contributing state atoms. * * TODO: there is actually no reason to tie this to context state -- the * generated code could be cached globally in the screen. */ static void make_variant_key(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, struct lp_fragment_shader_variant_key *key) { unsigned i; memset(key, 0, sizeof *key); if(lp->framebuffer.zsbuf && lp->depth_stencil->depth.enabled) { key->zsbuf_format = lp->framebuffer.zsbuf->format; memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth); } key->alpha.enabled = lp->depth_stencil->alpha.enabled; if(key->alpha.enabled) key->alpha.func = lp->depth_stencil->alpha.func; /* alpha.ref_value is passed in jit_context */ if(lp->framebuffer.cbufs[0]) { const struct util_format_description *format_desc; unsigned chan; memcpy(&key->blend, lp->blend, sizeof key->blend); format_desc = util_format_description(lp->framebuffer.cbufs[0]->format); assert(format_desc->layout == UTIL_FORMAT_COLORSPACE_RGB || format_desc->layout == UTIL_FORMAT_COLORSPACE_SRGB); /* mask out color channels not present in the color buffer */ for(chan = 0; chan < 4; ++chan) { enum util_format_swizzle swizzle = format_desc->swizzle[chan]; if(swizzle > 4) key->blend.colormask &= ~(1 << chan); } } for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]); }
/** * We need to generate several variants of the fragment pipeline to match * all the combinations of the contributing state atoms. * * TODO: there is actually no reason to tie this to context state -- the * generated code could be cached globally in the screen. */ static void make_variant_key(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, struct lp_fragment_shader_variant_key *key) { unsigned i; memset(key, 0, shader->variant_key_size); if (lp->framebuffer.zsbuf) { if (lp->depth_stencil->depth.enabled) { key->zsbuf_format = lp->framebuffer.zsbuf->format; memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth); } if (lp->depth_stencil->stencil[0].enabled) { key->zsbuf_format = lp->framebuffer.zsbuf->format; memcpy(&key->stencil, &lp->depth_stencil->stencil, sizeof key->stencil); } } key->alpha.enabled = lp->depth_stencil->alpha.enabled; if(key->alpha.enabled) key->alpha.func = lp->depth_stencil->alpha.func; /* alpha.ref_value is passed in jit_context */ key->flatshade = lp->rasterizer->flatshade; if (lp->active_query_count) { key->occlusion_count = TRUE; } if (lp->framebuffer.nr_cbufs) { memcpy(&key->blend, lp->blend, sizeof key->blend); } key->nr_cbufs = lp->framebuffer.nr_cbufs; for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { enum pipe_format format = lp->framebuffer.cbufs[i]->format; struct pipe_rt_blend_state *blend_rt = &key->blend.rt[i]; const struct util_format_description *format_desc; key->cbuf_format[i] = format; format_desc = util_format_description(format); assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB || format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB); blend_rt->colormask = lp->blend->rt[i].colormask; /* * Mask out color channels not present in the color buffer. */ blend_rt->colormask &= util_format_colormask(format_desc); /* * Our swizzled render tiles always have an alpha channel, but the linear * render target format often does not, so force here the dst alpha to be * one. * * This is not a mere optimization. Wrong results will be produced if the * dst alpha is used, the dst format does not have alpha, and the previous * rendering was not flushed from the swizzled to linear buffer. For * example, NonPowTwo DCT. * * TODO: This should be generalized to all channels for better * performance, but only alpha causes correctness issues. */ if (format_desc->swizzle[3] > UTIL_FORMAT_SWIZZLE_W) { blend_rt->rgb_src_factor = force_dst_alpha_one(blend_rt->rgb_src_factor, FALSE); blend_rt->rgb_dst_factor = force_dst_alpha_one(blend_rt->rgb_dst_factor, FALSE); blend_rt->alpha_src_factor = force_dst_alpha_one(blend_rt->alpha_src_factor, TRUE); blend_rt->alpha_dst_factor = force_dst_alpha_one(blend_rt->alpha_dst_factor, TRUE); } } /* This value will be the same for all the variants of a given shader: */ key->nr_samplers = shader->info.file_max[TGSI_FILE_SAMPLER] + 1; for(i = 0; i < key->nr_samplers; ++i) { if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) { lp_sampler_static_state(&key->sampler[i], lp->fragment_sampler_views[i], lp->sampler[i]); } } }