+ output_smask = LLVMBuildLoad(builder, outputs[smaski][0], "smask");
+ output_smask = LLVMBuildBitCast(builder, output_smask, smask_bld.vec_type, "");
+
+ if (key->min_samples > 1) {
+ /* only the bit corresponding to this sample is to be used. */
+ LLVMValueRef tmp_mask = LLVMBuildLoad(builder, out_sample_mask_storage, "tmp_mask");
+ LLVMValueRef out_smask_idx = LLVMBuildShl(builder, lp_build_const_int32(gallivm, 1), sample_loop_state.counter, "");
+ LLVMValueRef smask_bit = LLVMBuildAnd(builder, output_smask, lp_build_broadcast(gallivm, int_vec_type, out_smask_idx), "");
+ output_smask = LLVMBuildOr(builder, tmp_mask, smask_bit, "");
+ }
+
+ LLVMBuildStore(builder, output_smask, out_sample_mask_storage);
+ }
+
+ /* Color write - per fragment sample */
+ for (attrib = 0; attrib < shader->info.base.num_outputs; ++attrib)
+ {
+ unsigned cbuf = shader->info.base.output_semantic_index[attrib];
+ if ((shader->info.base.output_semantic_name[attrib] == TGSI_SEMANTIC_COLOR) &&
+ ((cbuf < key->nr_cbufs) || (cbuf == 1 && dual_source_blend)))
+ {
+ for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
+ if(outputs[attrib][chan]) {
+ /* XXX: just initialize outputs to point at colors[] and
+ * skip this.
+ */
+ LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], "");
+ LLVMValueRef color_ptr;
+ LLVMValueRef color_idx = loop_state.counter;
+ if (key->min_samples > 1)
+ color_idx = LLVMBuildAdd(builder, color_idx,
+ LLVMBuildMul(builder, sample_loop_state.counter, num_loop, ""), "");
+ color_ptr = LLVMBuildGEP(builder, out_color[cbuf][chan],
+ &color_idx, 1, "");
+ lp_build_name(out, "color%u.%c", attrib, "rgba"[chan]);
+ LLVMBuildStore(builder, out, color_ptr);
+ }
+ }
+ }
+ }
+
+ if (key->multisample && key->min_samples > 1) {
+ LLVMBuildStore(builder, lp_build_mask_value(&mask), s_mask_ptr);
+ lp_build_for_loop_end(&sample_loop_state);
+ }
+
+ if (key->multisample) {
+ /* execute depth test for each sample */
+ lp_build_for_loop_begin(&sample_loop_state, gallivm,
+ lp_build_const_int32(gallivm, 0),
+ LLVMIntULT, lp_build_const_int32(gallivm, key->coverage_samples),
+ lp_build_const_int32(gallivm, 1));
+
+ /* load the per-sample coverage mask */
+ LLVMValueRef s_mask_idx = LLVMBuildMul(builder, sample_loop_state.counter, num_loop, "");
+ s_mask_idx = LLVMBuildAdd(builder, s_mask_idx, loop_state.counter, "");
+ s_mask_ptr = LLVMBuildGEP(builder, mask_store, &s_mask_idx, 1, "");
+
+ /* combine the execution mask post fragment shader with the coverage mask. */
+ s_mask = LLVMBuildLoad(builder, s_mask_ptr, "");
+ if (key->min_samples == 1)
+ s_mask = LLVMBuildAnd(builder, s_mask, lp_build_mask_value(&mask), "");
+
+ /* if the shader writes sample mask use that */
+ if (shader->info.base.writes_samplemask) {
+ LLVMValueRef out_smask_idx = LLVMBuildShl(builder, lp_build_const_int32(gallivm, 1), sample_loop_state.counter, "");
+ out_smask_idx = lp_build_broadcast(gallivm, int_vec_type, out_smask_idx);
+ LLVMValueRef output_smask = LLVMBuildLoad(builder, out_sample_mask_storage, "");
+ LLVMValueRef smask_bit = LLVMBuildAnd(builder, output_smask, out_smask_idx, "");
+ LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntNE, smask_bit, lp_build_const_int_vec(gallivm, int_type, 0), "");
+ smask_bit = LLVMBuildSExt(builder, cmp, int_vec_type, "");
+
+ s_mask = LLVMBuildAnd(builder, s_mask, smask_bit, "");
+ }
+ }
+
+ depth_ptr = depth_base_ptr;
+ if (key->multisample) {
+ LLVMValueRef sample_offset = LLVMBuildMul(builder, sample_loop_state.counter, depth_sample_stride, "");
+ depth_ptr = LLVMBuildGEP(builder, depth_ptr, &sample_offset, 1, "");