return lp_build_clamp(&f32_bld, z, min_depth, max_depth);
}
+static void
+lp_build_sample_alpha_to_coverage(struct gallivm_state *gallivm,
+ struct lp_type type,
+ unsigned coverage_samples,
+ LLVMValueRef num_loop,
+ LLVMValueRef loop_counter,
+ LLVMValueRef coverage_mask_store,
+ LLVMValueRef alpha)
+{
+ struct lp_build_context bld;
+ LLVMBuilderRef builder = gallivm->builder;
+ float step = 1.0 / coverage_samples;
+
+ lp_build_context_init(&bld, gallivm, type);
+ for (unsigned s = 0; s < coverage_samples; s++) {
+ LLVMValueRef alpha_ref_value = lp_build_const_vec(gallivm, type, step * s);
+ LLVMValueRef test = lp_build_cmp(&bld, PIPE_FUNC_GREATER, alpha, alpha_ref_value);
+
+ LLVMValueRef s_mask_idx = LLVMBuildMul(builder, lp_build_const_int32(gallivm, s), num_loop, "");
+ s_mask_idx = LLVMBuildAdd(builder, s_mask_idx, loop_counter, "");
+ LLVMValueRef s_mask_ptr = LLVMBuildGEP(builder, coverage_mask_store, &s_mask_idx, 1, "");
+ LLVMValueRef s_mask = LLVMBuildLoad(builder, s_mask_ptr, "");
+ s_mask = LLVMBuildAnd(builder, s_mask, test, "");
+ LLVMBuildStore(builder, s_mask, s_mask_ptr);
+ }
+}
/**
* Generate the fragment shader, depth/stencil test, and alpha tests.
LLVMBuilderRef builder,
struct lp_type type,
LLVMValueRef context_ptr,
+ LLVMValueRef sample_pos_array,
LLVMValueRef num_loop,
struct lp_build_interp_soa_context *interp,
const struct lp_build_sampler_soa *sampler,
const struct lp_build_image_soa *image,
LLVMValueRef mask_store,
LLVMValueRef (*out_color)[4],
- LLVMValueRef depth_ptr,
+ LLVMValueRef depth_base_ptr,
LLVMValueRef depth_stride,
+ LLVMValueRef depth_sample_stride,
LLVMValueRef facing,
LLVMValueRef thread_data_ptr)
{
const struct tgsi_token *tokens = shader->base.tokens;
struct lp_type int_type = lp_int_type(type);
LLVMTypeRef vec_type, int_vec_type;
- LLVMValueRef mask_ptr, mask_val;
+ LLVMValueRef mask_ptr = NULL, mask_val = NULL;
LLVMValueRef consts_ptr, num_consts_ptr;
LLVMValueRef ssbo_ptr, num_ssbo_ptr;
LLVMValueRef z;
LLVMValueRef z_value, s_value;
LLVMValueRef z_fb, s_fb;
+ LLVMValueRef depth_ptr;
LLVMValueRef stencil_refs[2];
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
- struct lp_build_for_loop_state loop_state;
+ LLVMValueRef zs_samples = lp_build_const_int32(gallivm, key->zsbuf_nr_samples);
+ struct lp_build_for_loop_state loop_state, sample_loop_state;
struct lp_build_mask_context mask;
/*
* TODO: figure out if simple_shader optimization is really worthwile to
ssbo_ptr = lp_jit_context_ssbos(gallivm, context_ptr);
num_ssbo_ptr = lp_jit_context_num_ssbos(gallivm, context_ptr);
- lp_build_for_loop_begin(&loop_state, gallivm,
- lp_build_const_int32(gallivm, 0),
- LLVMIntULT,
- num_loop,
- lp_build_const_int32(gallivm, 1));
-
- mask_ptr = LLVMBuildGEP(builder, mask_store,
- &loop_state.counter, 1, "mask_ptr");
- mask_val = LLVMBuildLoad(builder, mask_ptr, "");
-
memset(outputs, 0, sizeof outputs);
for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
}
}
+ lp_build_for_loop_begin(&loop_state, gallivm,
+ lp_build_const_int32(gallivm, 0),
+ LLVMIntULT,
+ num_loop,
+ lp_build_const_int32(gallivm, 1));
+
+ if (key->multisample) {
+ /* create shader execution mask by combining all sample masks. */
+ for (unsigned s = 0; s < key->coverage_samples; s++) {
+ LLVMValueRef s_mask_idx = LLVMBuildMul(builder, num_loop, lp_build_const_int32(gallivm, s), "");
+ s_mask_idx = LLVMBuildAdd(builder, s_mask_idx, loop_state.counter, "");
+ LLVMValueRef s_mask = lp_build_pointer_get(builder, mask_store, s_mask_idx);
+ if (s == 0)
+ mask_val = s_mask;
+ else
+ mask_val = LLVMBuildOr(builder, s_mask, mask_val, "");
+ }
+ } else {
+ mask_ptr = LLVMBuildGEP(builder, mask_store,
+ &loop_state.counter, 1, "mask_ptr");
+ mask_val = LLVMBuildLoad(builder, mask_ptr, "");
+ }
/* 'mask' will control execution based on quad's pixel alive/killed state */
lp_build_mask_begin(&mask, gallivm, type, mask_val);
if (!(depth_mode & EARLY_DEPTH_TEST) && !simple_shader)
lp_build_mask_check(&mask);
- lp_build_interp_soa_update_pos_dyn(interp, gallivm, loop_state.counter);
+ /* Create storage for recombining sample masks after early Z pass. */
+ LLVMValueRef s_mask_or = lp_build_alloca(gallivm, lp_build_int_vec_type(gallivm, type), "cov_mask_early_depth");
+ LLVMBuildStore(builder, LLVMConstNull(lp_build_int_vec_type(gallivm, type)), s_mask_or);
+
+ LLVMValueRef s_mask = NULL, s_mask_ptr = NULL;
+ LLVMValueRef z_sample_value_store = NULL, s_sample_value_store = NULL;
+ LLVMValueRef z_fb_store = NULL, s_fb_store = NULL;
+ LLVMTypeRef z_type = NULL, z_fb_type = NULL;
+
+ /* Run early depth once per sample */
+ if (key->multisample) {
+
+ if (zs_format_desc) {
+ struct lp_type zs_type = lp_depth_type(zs_format_desc, type.length);
+ struct lp_type z_type = zs_type;
+ struct lp_type s_type = zs_type;
+ if (zs_format_desc->block.bits < type.width)
+ z_type.width = type.width;
+ else if (zs_format_desc->block.bits > 32) {
+ z_type.width = z_type.width / 2;
+ s_type.width = s_type.width / 2;
+ s_type.floating = 0;
+ }
+ z_sample_value_store = lp_build_array_alloca(gallivm, lp_build_int_vec_type(gallivm, type),
+ zs_samples, "z_sample_store");
+ s_sample_value_store = lp_build_array_alloca(gallivm, lp_build_int_vec_type(gallivm, type),
+ zs_samples, "s_sample_store");
+ z_fb_store = lp_build_array_alloca(gallivm, lp_build_vec_type(gallivm, z_type),
+ zs_samples, "z_fb_store");
+ s_fb_store = lp_build_array_alloca(gallivm, lp_build_vec_type(gallivm, s_type),
+ zs_samples, "s_fb_store");
+ }
+ 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));
+
+ 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, "");
+
+ s_mask = LLVMBuildLoad(builder, s_mask_ptr, "");
+ s_mask = LLVMBuildAnd(builder, s_mask, mask_val, "");
+ }
+
+
+ /* for multisample Z needs to be interpolated at sample points for testing. */
+ lp_build_interp_soa_update_pos_dyn(interp, gallivm, loop_state.counter, key->multisample ? sample_loop_state.counter : NULL);
z = interp->pos[2];
+ 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, "");
+ }
+
if (depth_mode & EARLY_DEPTH_TEST) {
/*
* Clamp according to ARB_depth_clamp semantics.
key->stencil,
type,
zs_format_desc,
- &mask,
+ key->multisample ? NULL : &mask,
+ &s_mask,
stencil_refs,
z, z_fb, s_fb,
facing,
* stencil test otherwise new stencil values may not get written if all
* fragments got killed by depth/stencil test.
*/
- if (!simple_shader && key->stencil[0].enabled)
+ if (!simple_shader && key->stencil[0].enabled && !key->multisample)
lp_build_mask_check(&mask);
+
+ if (key->multisample) {
+ z_fb_type = LLVMTypeOf(z_fb);
+ z_type = LLVMTypeOf(z_value);
+ lp_build_pointer_set(builder, z_sample_value_store, sample_loop_state.counter, LLVMBuildBitCast(builder, z_value, lp_build_int_vec_type(gallivm, type), ""));
+ lp_build_pointer_set(builder, s_sample_value_store, sample_loop_state.counter, LLVMBuildBitCast(builder, s_value, lp_build_int_vec_type(gallivm, type), ""));
+ lp_build_pointer_set(builder, z_fb_store, sample_loop_state.counter, z_fb);
+ lp_build_pointer_set(builder, s_fb_store, sample_loop_state.counter, s_fb);
+ }
}
- lp_build_interp_soa_update_inputs_dyn(interp, gallivm, loop_state.counter, NULL);
+ if (key->multisample) {
+ /*
+ * Store the post-early Z coverage mask.
+ * Recombine the resulting coverage masks post early Z into the fragment
+ * shader execution mask.
+ */
+ LLVMValueRef tmp_s_mask_or = LLVMBuildLoad(builder, s_mask_or, "");
+ tmp_s_mask_or = LLVMBuildOr(builder, tmp_s_mask_or, s_mask, "");
+ LLVMBuildStore(builder, tmp_s_mask_or, s_mask_or);
+
+ LLVMBuildStore(builder, s_mask, s_mask_ptr);
+
+ lp_build_for_loop_end(&sample_loop_state);
+
+ /* recombined all the coverage masks in the shader exec mask. */
+ tmp_s_mask_or = LLVMBuildLoad(builder, s_mask_or, "");
+ lp_build_mask_update(&mask, tmp_s_mask_or);
+
+ /* for multisample Z needs to be re interpolated at pixel center */
+ lp_build_interp_soa_update_pos_dyn(interp, gallivm, loop_state.counter, NULL);
+ }
+
+ system_values.sample_pos = sample_pos_array;
+
+ lp_build_interp_soa_update_inputs_dyn(interp, gallivm, loop_state.counter, NULL, NULL);
struct lp_build_tgsi_params params;
memset(¶ms, 0, sizeof(params));
if (color0 != -1 && outputs[color0][3]) {
LLVMValueRef alpha = LLVMBuildLoad(builder, outputs[color0][3], "alpha");
- lp_build_alpha_to_coverage(gallivm, type,
- &mask, alpha,
- (depth_mode & LATE_DEPTH_TEST) != 0);
+ if (!key->multisample) {
+ lp_build_alpha_to_coverage(gallivm, type,
+ &mask, alpha,
+ (depth_mode & LATE_DEPTH_TEST) != 0);
+ } else {
+ lp_build_sample_alpha_to_coverage(gallivm, type, key->coverage_samples, num_loop,
+ loop_state.counter,
+ mask_store, alpha);
+ }
+ }
+ }
+ if (key->blend.alpha_to_one && key->multisample) {
+ 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)))
+ if (outputs[cbuf][3]) {
+ LLVMBuildStore(builder, lp_build_const_vec(gallivm, type, 1.0), outputs[cbuf][3]);
+ }
}
}
-
if (shader->info.base.writes_samplemask) {
int smaski = find_output_by_semantic(&shader->info.base,
TGSI_SEMANTIC_SAMPLEMASK,
lp_build_mask_update(&mask, smask);
}
+ 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, "");
+ s_mask = LLVMBuildAnd(builder, s_mask, lp_build_mask_value(&mask), "");
+ }
+
+ 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, "");
+ }
+
/* Late Z test */
if (depth_mode & LATE_DEPTH_TEST) {
int pos0 = find_output_by_semantic(&shader->info.base,
key->stencil,
type,
zs_format_desc,
- &mask,
+ key->multisample ? NULL : &mask,
+ &s_mask,
stencil_refs,
z, z_fb, s_fb,
facing,
* depth value, update from zs_value with the new mask value and
* write that out.
*/
+ if (key->multisample) {
+ z_value = LLVMBuildBitCast(builder, lp_build_pointer_get(builder, z_sample_value_store, sample_loop_state.counter), z_type, "");;
+ s_value = lp_build_pointer_get(builder, s_sample_value_store, sample_loop_state.counter);
+ z_fb = LLVMBuildBitCast(builder, lp_build_pointer_get(builder, z_fb_store, sample_loop_state.counter), z_fb_type, "");
+ s_fb = lp_build_pointer_get(builder, s_fb_store, sample_loop_state.counter);
+ }
lp_build_depth_stencil_write_swizzled(gallivm, type,
zs_format_desc, key->resource_1d,
- &mask, z_fb, s_fb, loop_state.counter,
+ key->multisample ? s_mask : lp_build_mask_value(&mask), z_fb, s_fb, loop_state.counter,
depth_ptr, depth_stride,
z_value, s_value);
}
+ if (key->multisample) {
+ /* store the sample mask for this loop */
+ LLVMBuildStore(builder, s_mask, s_mask_ptr);
+ lp_build_for_loop_end(&sample_loop_state);
+ }
/* Color write */
for (attrib = 0; attrib < shader->info.base.num_outputs; ++attrib)
}
mask_val = lp_build_mask_end(&mask);
- LLVMBuildStore(builder, mask_val, mask_ptr);
+ if (!key->multisample)
+ LLVMBuildStore(builder, mask_val, mask_ptr);
lp_build_for_loop_end(&loop_state);
}
struct lp_build_sampler_soa *sampler;
struct lp_build_image_soa *image;
struct lp_build_interp_soa_context interp;
- LLVMValueRef fs_mask[16 / 4];
+ LLVMValueRef fs_mask[(16 / 4) * LP_MAX_SAMPLES];
LLVMValueRef fs_out_color[PIPE_MAX_COLOR_BUFS][TGSI_NUM_CHANNELS][16 / 4];
LLVMValueRef function;
LLVMValueRef facing;
arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* a0 */
arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dadx */
arg_types[6] = LLVMPointerType(fs_elem_type, 0); /* dady */
- arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */
+ arg_types[7] = LLVMPointerType(LLVMPointerType(int8_type, 0), 0); /* color */
arg_types[8] = LLVMPointerType(int8_type, 0); /* depth */
arg_types[9] = LLVMInt64TypeInContext(gallivm->context); /* mask_input */
arg_types[10] = variant->jit_thread_data_ptr_type; /* per thread data */
{
LLVMValueRef num_loop = lp_build_const_int32(gallivm, num_fs);
LLVMTypeRef mask_type = lp_build_int_vec_type(gallivm, fs_type);
+ LLVMValueRef num_loop_samp = lp_build_const_int32(gallivm, num_fs * key->coverage_samples);
LLVMValueRef mask_store = lp_build_array_alloca(gallivm, mask_type,
- num_loop, "mask_store");
+ num_loop_samp, "mask_store");
+
+ LLVMTypeRef flt_type = LLVMFloatTypeInContext(gallivm->context);
+ LLVMValueRef glob_sample_pos = LLVMAddGlobal(gallivm->module, flt_type, "");
+ LLVMValueRef sample_pos_array;
+
+ if (key->multisample && key->coverage_samples == 4) {
+ LLVMValueRef sample_pos_arr[8];
+ for (unsigned i = 0; i < 4; i++) {
+ sample_pos_arr[i * 2] = LLVMConstReal(flt_type, lp_sample_pos_4x[i][0]);
+ sample_pos_arr[i * 2 + 1] = LLVMConstReal(flt_type, lp_sample_pos_4x[i][1]);
+ }
+ sample_pos_array = LLVMConstArray(LLVMFloatTypeInContext(gallivm->context), sample_pos_arr, 8);
+ } else {
+ LLVMValueRef sample_pos_arr[2];
+ sample_pos_arr[0] = LLVMConstReal(flt_type, 0.5);
+ sample_pos_arr[1] = LLVMConstReal(flt_type, 0.5);
+ sample_pos_array = LLVMConstArray(LLVMFloatTypeInContext(gallivm->context), sample_pos_arr, 2);
+ }
+ LLVMSetInitializer(glob_sample_pos, sample_pos_array);
+
LLVMValueRef color_store[PIPE_MAX_COLOR_BUFS][TGSI_NUM_CHANNELS];
boolean pixel_center_integer =
shader->info.base.properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER];
shader->info.base.num_inputs,
inputs,
pixel_center_integer,
- 1, NULL, num_loop,
+ key->coverage_samples, glob_sample_pos,
+ num_loop,
key->depth_clamp,
builder, fs_type,
a0_ptr, dadx_ptr, dady_ptr,
x, y);
for (i = 0; i < num_fs; i++) {
- LLVMValueRef mask;
- LLVMValueRef indexi = lp_build_const_int32(gallivm, i);
- LLVMValueRef mask_ptr = LLVMBuildGEP(builder, mask_store,
- &indexi, 1, "mask_ptr");
+ if (key->multisample) {
+ LLVMValueRef smask_val = LLVMBuildLoad(builder, lp_jit_context_sample_mask(gallivm, context_ptr), "");
- if (partial_mask) {
- mask = generate_quad_mask(gallivm, fs_type,
- i*fs_type.length/4, 0, mask_input);
- }
- else {
- mask = lp_build_const_int_vec(gallivm, fs_type, ~0);
+ /*
+ * For multisampling, extract the per-sample mask from the incoming 64-bit mask,
+ * store to the per sample mask storage. Or all of them together to generate
+ * the fragment shader mask. (sample shading TODO).
+ * Take the incoming state coverage mask into account.
+ */
+ for (unsigned s = 0; s < key->coverage_samples; s++) {
+ LLVMValueRef sindexi = lp_build_const_int32(gallivm, i + (s * num_fs));
+ LLVMValueRef sample_mask_ptr = LLVMBuildGEP(builder, mask_store,
+ &sindexi, 1, "sample_mask_ptr");
+ LLVMValueRef s_mask = generate_quad_mask(gallivm, fs_type,
+ i*fs_type.length/4, s, mask_input);
+
+ LLVMValueRef smask_bit = LLVMBuildAnd(builder, smask_val, lp_build_const_int32(gallivm, (1 << s)), "");
+ LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntNE, smask_bit, lp_build_const_int32(gallivm, 0), "");
+ smask_bit = LLVMBuildSExt(builder, cmp, int32_type, "");
+ smask_bit = lp_build_broadcast(gallivm, mask_type, smask_bit);
+
+ s_mask = LLVMBuildAnd(builder, s_mask, smask_bit, "");
+ LLVMBuildStore(builder, s_mask, sample_mask_ptr);
+ }
+ } else {
+ LLVMValueRef mask;
+ LLVMValueRef indexi = lp_build_const_int32(gallivm, i);
+ LLVMValueRef mask_ptr = LLVMBuildGEP(builder, mask_store,
+ &indexi, 1, "mask_ptr");
+
+ if (partial_mask) {
+ mask = generate_quad_mask(gallivm, fs_type,
+ i*fs_type.length/4, 0, mask_input);
+ }
+ else {
+ mask = lp_build_const_int_vec(gallivm, fs_type, ~0);
+ }
+ LLVMBuildStore(builder, mask, mask_ptr);
}
- LLVMBuildStore(builder, mask, mask_ptr);
}
generate_fs_loop(gallivm,
builder,
fs_type,
context_ptr,
+ glob_sample_pos,
num_loop,
&interp,
sampler,
color_store,
depth_ptr,
depth_stride,
+ depth_sample_stride,
facing,
thread_data_ptr);
for (i = 0; i < num_fs; i++) {
LLVMValueRef indexi = lp_build_const_int32(gallivm, i);
- LLVMValueRef ptr = LLVMBuildGEP(builder, mask_store,
- &indexi, 1, "");
- fs_mask[i] = LLVMBuildLoad(builder, ptr, "mask");
+ LLVMValueRef ptr;
+ for (unsigned s = 0; s < key->coverage_samples; s++) {
+ int idx = (i + (s * num_fs));
+ LLVMValueRef sindexi = lp_build_const_int32(gallivm, idx);
+ ptr = LLVMBuildGEP(builder, mask_store, &sindexi, 1, "");
+
+ fs_mask[idx] = LLVMBuildLoad(builder, ptr, "smask");
+ }
+
/* This is fucked up need to reorganize things */
for (cbuf = 0; cbuf < key->nr_cbufs; cbuf++) {
for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
if (key->cbuf_format[cbuf] != PIPE_FORMAT_NONE) {
LLVMValueRef color_ptr;
LLVMValueRef stride;
+ LLVMValueRef sample_stride = NULL;
LLVMValueRef index = lp_build_const_int32(gallivm, cbuf);
boolean do_branch = ((key->depth.enabled
&index, 1, ""),
"");
- lp_build_name(color_ptr, "color_ptr%d", cbuf);
-
stride = LLVMBuildLoad(builder,
LLVMBuildGEP(builder, stride_ptr, &index, 1, ""),
"");
- generate_unswizzled_blend(gallivm, cbuf, variant,
- key->cbuf_format[cbuf],
- num_fs, fs_type, fs_mask, fs_out_color,
- context_ptr, color_ptr, stride,
- partial_mask, do_branch);
+ if (key->multisample)
+ sample_stride = LLVMBuildLoad(builder,
+ LLVMBuildGEP(builder, color_sample_stride_ptr,
+ &index, 1, ""), "");
+
+ for (unsigned s = 0; s < key->cbuf_nr_samples[cbuf]; s++) {
+ unsigned mask_idx = num_fs * (key->multisample ? s : 0);
+ LLVMValueRef out_ptr = color_ptr;;
+
+ if (key->multisample) {
+ LLVMValueRef sample_offset = LLVMBuildMul(builder, sample_stride, lp_build_const_int32(gallivm, s), "");
+ out_ptr = LLVMBuildGEP(builder, out_ptr, &sample_offset, 1, "");
+ }
+ out_ptr = LLVMBuildBitCast(builder, out_ptr, LLVMPointerType(blend_vec_type, 0), "");
+
+ lp_build_name(out_ptr, "color_ptr%d", cbuf);
+
+ generate_unswizzled_blend(gallivm, cbuf, variant,
+ key->cbuf_format[cbuf],
+ num_fs, fs_type, &fs_mask[mask_idx], fs_out_color,
+ context_ptr, out_ptr, stride,
+ partial_mask, do_branch);
+ }
}
}