- const struct util_format_description *zs_format_desc = NULL;
- const struct tgsi_token *tokens = shader->base.tokens;
- LLVMTypeRef vec_type;
- LLVMValueRef consts_ptr;
- LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
- LLVMValueRef z;
- LLVMValueRef zs_value = NULL;
- LLVMValueRef stencil_refs[2];
- struct lp_build_mask_context mask;
- boolean simple_shader = (shader->info.base.file_count[TGSI_FILE_SAMPLER] == 0 &&
- shader->info.base.num_inputs < 3 &&
- shader->info.base.num_instructions < 8);
- unsigned attrib;
- unsigned chan;
- unsigned cbuf;
- unsigned depth_mode;
- struct lp_bld_tgsi_system_values system_values;
-
- memset(&system_values, 0, sizeof(system_values));
-
- if (key->depth.enabled ||
- key->stencil[0].enabled ||
- key->stencil[1].enabled) {
-
- zs_format_desc = util_format_description(key->zsbuf_format);
- assert(zs_format_desc);
-
- if (!shader->info.base.writes_z) {
- if (key->alpha.enabled || shader->info.base.uses_kill)
- /* With alpha test and kill, can do the depth test early
- * and hopefully eliminate some quads. But need to do a
- * special deferred depth write once the final mask value
- * is known.
- */
- depth_mode = EARLY_DEPTH_TEST | LATE_DEPTH_WRITE;
- else
- depth_mode = EARLY_DEPTH_TEST | EARLY_DEPTH_WRITE;
- }
- else {
- depth_mode = LATE_DEPTH_TEST | LATE_DEPTH_WRITE;
- }
-
- if (!(key->depth.enabled && key->depth.writemask) &&
- !(key->stencil[0].enabled && key->stencil[0].writemask))
- depth_mode &= ~(LATE_DEPTH_WRITE | EARLY_DEPTH_WRITE);
- }
- else {
- depth_mode = 0;
- }
-
- assert(i < 4);
-
- stencil_refs[0] = lp_jit_context_stencil_ref_front_value(gallivm, context_ptr);
- stencil_refs[1] = lp_jit_context_stencil_ref_back_value(gallivm, context_ptr);
-
- vec_type = lp_build_vec_type(gallivm, type);
-
- consts_ptr = lp_jit_context_constants(gallivm, context_ptr);
-
- memset(outputs, 0, sizeof outputs);
-
- /* Declare the color and z variables */
- for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
- for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
- color[cbuf][chan] = lp_build_alloca(gallivm, vec_type, "color");
- }
- }
-
- /* do triangle edge testing */
- if (partial_mask) {
- *pmask = generate_quad_mask(gallivm, type,
- i*type.length/4, mask_input);
- }
- else {
- *pmask = lp_build_const_int_vec(gallivm, type, ~0);
- }
-
- /* 'mask' will control execution based on quad's pixel alive/killed state */
- lp_build_mask_begin(&mask, gallivm, type, *pmask);
-
- if (!(depth_mode & EARLY_DEPTH_TEST) && !simple_shader)
- lp_build_mask_check(&mask);
-
- lp_build_interp_soa_update_pos(interp, gallivm, i*type.length/4);
- z = interp->pos[2];
-
- if (depth_mode & EARLY_DEPTH_TEST) {
- lp_build_depth_stencil_test(gallivm,
- &key->depth,
- key->stencil,
- type,
- zs_format_desc,
- &mask,
- stencil_refs,
- z,
- depth_ptr, facing,
- &zs_value,
- !simple_shader);
-
- if (depth_mode & EARLY_DEPTH_WRITE) {
- lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr, zs_value);
- }
- }
-
- lp_build_interp_soa_update_inputs(interp, gallivm, i*type.length/4);
-
- /* Build the actual shader */
- lp_build_tgsi_soa(gallivm, tokens, type, &mask,
- consts_ptr, &system_values,
- interp->pos, interp->inputs,
- outputs, sampler, &shader->info.base);
-
- /* Alpha test */
- if (key->alpha.enabled) {
- int color0 = find_output_by_semantic(&shader->info.base,
- TGSI_SEMANTIC_COLOR,
- 0);
-
- if (color0 != -1 && outputs[color0][3]) {
- const struct util_format_description *cbuf_format_desc;
- LLVMValueRef alpha = LLVMBuildLoad(builder, outputs[color0][3], "alpha");
- LLVMValueRef alpha_ref_value;
-
- alpha_ref_value = lp_jit_context_alpha_ref_value(gallivm, context_ptr);
- alpha_ref_value = lp_build_broadcast(gallivm, vec_type, alpha_ref_value);
-
- cbuf_format_desc = util_format_description(key->cbuf_format[0]);
-
- lp_build_alpha_test(gallivm, key->alpha.func, type, cbuf_format_desc,
- &mask, alpha, alpha_ref_value,
- (depth_mode & LATE_DEPTH_TEST) != 0);
- }
- }
-
- /* Late Z test */
- if (depth_mode & LATE_DEPTH_TEST) {
- int pos0 = find_output_by_semantic(&shader->info.base,
- TGSI_SEMANTIC_POSITION,
- 0);
-
- if (pos0 != -1 && outputs[pos0][2]) {
- z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
- }
-
- lp_build_depth_stencil_test(gallivm,
- &key->depth,
- key->stencil,
- type,
- zs_format_desc,
- &mask,
- stencil_refs,
- z,
- depth_ptr, facing,
- &zs_value,
- !simple_shader);
- /* Late Z write */
- if (depth_mode & LATE_DEPTH_WRITE) {
- lp_build_depth_write(gallivm, type, zs_format_desc, depth_ptr, zs_value);
- }
- }
- else if ((depth_mode & EARLY_DEPTH_TEST) &&
- (depth_mode & LATE_DEPTH_WRITE))
- {
- /* Need to apply a reduced mask to the depth write. Reload the
- * depth value, update from zs_value with the new mask value and
- * write that out.
- */
- lp_build_deferred_depth_write(gallivm,
- type,
- zs_format_desc,
- &mask,
- depth_ptr,
- zs_value);
- }