nir_ssa_def *mul = nir_vec2(b, nir_load_var(b, v->u_x_transform.multiplier),
nir_load_var(b, v->u_y_transform.multiplier));
- nir_ssa_def *pos = nir_ffma(b, src_pos, mul, offset);
-
- if (src_pos->num_components == 3) {
- /* Leave the sample id alone */
- pos = nir_vec3(b, nir_channel(b, pos, 0), nir_channel(b, pos, 1),
- nir_channel(b, src_pos, 2));
- }
-
- return pos;
+ return nir_ffma(b, src_pos, mul, offset);
}
static inline void
return nir_vec2(b, x_Y, y_Y);
}
+/**
+ * Emit code to compensate for the difference between MSAA and non-MSAA
+ * surfaces.
+ *
+ * This code modifies the X and Y coordinates according to the formula:
+ *
+ * (X', Y', S') = encode_msaa(num_samples, IMS, X, Y, S)
+ *
+ * (See brw_blorp_blit_program).
+ */
+static inline nir_ssa_def *
+blorp_nir_encode_msaa(nir_builder *b, nir_ssa_def *pos,
+ unsigned num_samples, enum intel_msaa_layout layout)
+{
+ assert(pos->num_components == 2 || pos->num_components == 3);
+
+ switch (layout) {
+ case INTEL_MSAA_LAYOUT_NONE:
+ assert(pos->num_components == 2);
+ return pos;
+ case INTEL_MSAA_LAYOUT_CMS:
+ /* We can't compensate for compressed layout since at this point in the
+ * program we haven't read from the MCS buffer.
+ */
+ unreachable("Bad layout in encode_msaa");
+ case INTEL_MSAA_LAYOUT_UMS:
+ /* No translation needed */
+ return pos;
+ case INTEL_MSAA_LAYOUT_IMS: {
+ nir_ssa_def *x_in = nir_channel(b, pos, 0);
+ nir_ssa_def *y_in = nir_channel(b, pos, 1);
+ nir_ssa_def *s_in = pos->num_components == 2 ? nir_imm_int(b, 0) :
+ nir_channel(b, pos, 2);
+
+ nir_ssa_def *x_out = nir_imm_int(b, 0);
+ nir_ssa_def *y_out = nir_imm_int(b, 0);
+ switch (num_samples) {
+ case 2:
+ case 4:
+ /* encode_msaa(2, IMS, X, Y, S) = (X', Y', 0)
+ * where X' = (X & ~0b1) << 1 | (S & 0b1) << 1 | (X & 0b1)
+ * Y' = Y
+ *
+ * encode_msaa(4, IMS, X, Y, S) = (X', Y', 0)
+ * where X' = (X & ~0b1) << 1 | (S & 0b1) << 1 | (X & 0b1)
+ * Y' = (Y & ~0b1) << 1 | (S & 0b10) | (Y & 0b1)
+ */
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0xfffffffe, 1);
+ x_out = nir_mask_shift_or(b, x_out, s_in, 0x1, 1);
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0x1, 0);
+ if (num_samples == 2) {
+ y_out = y_in;
+ } else {
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0xfffffffe, 1);
+ y_out = nir_mask_shift_or(b, y_out, s_in, 0x2, 0);
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0x1, 0);
+ }
+ break;
+
+ case 8:
+ /* encode_msaa(8, IMS, X, Y, S) = (X', Y', 0)
+ * where X' = (X & ~0b1) << 2 | (S & 0b100) | (S & 0b1) << 1
+ * | (X & 0b1)
+ * Y' = (Y & ~0b1) << 1 | (S & 0b10) | (Y & 0b1)
+ */
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0xfffffffe, 2);
+ x_out = nir_mask_shift_or(b, x_out, s_in, 0x4, 0);
+ x_out = nir_mask_shift_or(b, x_out, s_in, 0x1, 1);
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0x1, 0);
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0xfffffffe, 1);
+ y_out = nir_mask_shift_or(b, y_out, s_in, 0x2, 0);
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0x1, 0);
+ break;
+
+ default:
+ unreachable("Invalid number of samples for IMS layout");
+ }
+
+ return nir_vec2(b, x_out, y_out);
+ }
+
+ default:
+ unreachable("Invalid MSAA layout");
+ }
+}
+
+/**
+ * Emit code to compensate for the difference between MSAA and non-MSAA
+ * surfaces.
+ *
+ * This code modifies the X and Y coordinates according to the formula:
+ *
+ * (X', Y', S) = decode_msaa(num_samples, IMS, X, Y, S)
+ *
+ * (See brw_blorp_blit_program).
+ */
+static inline nir_ssa_def *
+blorp_nir_decode_msaa(nir_builder *b, nir_ssa_def *pos,
+ unsigned num_samples, enum intel_msaa_layout layout)
+{
+ assert(pos->num_components == 2 || pos->num_components == 3);
+
+ switch (layout) {
+ case INTEL_MSAA_LAYOUT_NONE:
+ /* No translation necessary, and S should already be zero. */
+ assert(pos->num_components == 2);
+ return pos;
+ case INTEL_MSAA_LAYOUT_CMS:
+ /* We can't compensate for compressed layout since at this point in the
+ * program we don't have access to the MCS buffer.
+ */
+ unreachable("Bad layout in encode_msaa");
+ case INTEL_MSAA_LAYOUT_UMS:
+ /* No translation necessary. */
+ return pos;
+ case INTEL_MSAA_LAYOUT_IMS: {
+ assert(pos->num_components == 2);
+
+ nir_ssa_def *x_in = nir_channel(b, pos, 0);
+ nir_ssa_def *y_in = nir_channel(b, pos, 1);
+
+ nir_ssa_def *x_out = nir_imm_int(b, 0);
+ nir_ssa_def *y_out = nir_imm_int(b, 0);
+ nir_ssa_def *s_out = nir_imm_int(b, 0);
+ switch (num_samples) {
+ case 2:
+ case 4:
+ /* decode_msaa(2, IMS, X, Y, 0) = (X', Y', S)
+ * where X' = (X & ~0b11) >> 1 | (X & 0b1)
+ * S = (X & 0b10) >> 1
+ *
+ * decode_msaa(4, IMS, X, Y, 0) = (X', Y', S)
+ * where X' = (X & ~0b11) >> 1 | (X & 0b1)
+ * Y' = (Y & ~0b11) >> 1 | (Y & 0b1)
+ * S = (Y & 0b10) | (X & 0b10) >> 1
+ */
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0xfffffffc, -1);
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0x1, 0);
+ if (num_samples == 2) {
+ y_out = y_in;
+ s_out = nir_mask_shift_or(b, s_out, x_in, 0x2, -1);
+ } else {
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0xfffffffc, -1);
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0x1, 0);
+ s_out = nir_mask_shift_or(b, s_out, x_in, 0x2, -1);
+ s_out = nir_mask_shift_or(b, s_out, y_in, 0x2, 0);
+ }
+ break;
+
+ case 8:
+ /* decode_msaa(8, IMS, X, Y, 0) = (X', Y', S)
+ * where X' = (X & ~0b111) >> 2 | (X & 0b1)
+ * Y' = (Y & ~0b11) >> 1 | (Y & 0b1)
+ * S = (X & 0b100) | (Y & 0b10) | (X & 0b10) >> 1
+ */
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0xfffffff8, -2);
+ x_out = nir_mask_shift_or(b, x_out, x_in, 0x1, 0);
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0xfffffffc, -1);
+ y_out = nir_mask_shift_or(b, y_out, y_in, 0x1, 0);
+ s_out = nir_mask_shift_or(b, s_out, x_in, 0x4, 0);
+ s_out = nir_mask_shift_or(b, s_out, y_in, 0x2, 0);
+ s_out = nir_mask_shift_or(b, s_out, x_in, 0x2, -1);
+ break;
+
+ default:
+ unreachable("Invalid number of samples for IMS layout");
+ }
+
+ return nir_vec3(b, x_out, y_out, s_out);
+ }
+
+ default:
+ unreachable("Invalid MSAA layout");
+ }
+}
+
+/**
+ * Count the number of trailing 1 bits in the given value. For example:
+ *
+ * count_trailing_one_bits(0) == 0
+ * count_trailing_one_bits(7) == 3
+ * count_trailing_one_bits(11) == 2
+ */
+static inline int count_trailing_one_bits(unsigned value)
+{
+#ifdef HAVE___BUILTIN_CTZ
+ return __builtin_ctz(~value);
+#else
+ return _mesa_bitcount(value & ~(value + 1));
+#endif
+}
+
+static nir_ssa_def *
+blorp_nir_manual_blend_average(nir_builder *b, nir_ssa_def *pos,
+ unsigned tex_samples,
+ enum intel_msaa_layout tex_layout,
+ enum brw_reg_type dst_type)
+{
+ /* If non-null, this is the outer-most if statement */
+ nir_if *outer_if = NULL;
+
+ nir_variable *color =
+ nir_local_variable_create(b->impl, glsl_vec4_type(), "color");
+
+ nir_ssa_def *mcs = NULL;
+ if (tex_layout == INTEL_MSAA_LAYOUT_CMS)
+ mcs = blorp_nir_txf_ms_mcs(b, pos);
+
+ /* We add together samples using a binary tree structure, e.g. for 4x MSAA:
+ *
+ * result = ((sample[0] + sample[1]) + (sample[2] + sample[3])) / 4
+ *
+ * This ensures that when all samples have the same value, no numerical
+ * precision is lost, since each addition operation always adds two equal
+ * values, and summing two equal floating point values does not lose
+ * precision.
+ *
+ * We perform this computation by treating the texture_data array as a
+ * stack and performing the following operations:
+ *
+ * - push sample 0 onto stack
+ * - push sample 1 onto stack
+ * - add top two stack entries
+ * - push sample 2 onto stack
+ * - push sample 3 onto stack
+ * - add top two stack entries
+ * - add top two stack entries
+ * - divide top stack entry by 4
+ *
+ * Note that after pushing sample i onto the stack, the number of add
+ * operations we do is equal to the number of trailing 1 bits in i. This
+ * works provided the total number of samples is a power of two, which it
+ * always is for i965.
+ *
+ * For integer formats, we replace the add operations with average
+ * operations and skip the final division.
+ */
+ nir_ssa_def *texture_data[4];
+ unsigned stack_depth = 0;
+ for (unsigned i = 0; i < tex_samples; ++i) {
+ assert(stack_depth == _mesa_bitcount(i)); /* Loop invariant */
+
+ /* Push sample i onto the stack */
+ assert(stack_depth < ARRAY_SIZE(texture_data));
+
+ nir_ssa_def *ms_pos = nir_vec3(b, nir_channel(b, pos, 0),
+ nir_channel(b, pos, 1),
+ nir_imm_int(b, i));
+ texture_data[stack_depth++] = blorp_nir_txf_ms(b, ms_pos, mcs, dst_type);
+
+ if (i == 0 && tex_layout == INTEL_MSAA_LAYOUT_CMS) {
+ /* The Ivy Bridge PRM, Vol4 Part1 p27 (Multisample Control Surface)
+ * suggests an optimization:
+ *
+ * "A simple optimization with probable large return in
+ * performance is to compare the MCS value to zero (indicating
+ * all samples are on sample slice 0), and sample only from
+ * sample slice 0 using ld2dss if MCS is zero."
+ *
+ * Note that in the case where the MCS value is zero, sampling from
+ * sample slice 0 using ld2dss and sampling from sample 0 using
+ * ld2dms are equivalent (since all samples are on sample slice 0).
+ * Since we have already sampled from sample 0, all we need to do is
+ * skip the remaining fetches and averaging if MCS is zero.
+ */
+ nir_ssa_def *mcs_zero =
+ nir_ieq(b, nir_channel(b, mcs, 0), nir_imm_int(b, 0));
+ nir_if *if_stmt = nir_if_create(b->shader);
+ if_stmt->condition = nir_src_for_ssa(mcs_zero);
+ nir_cf_node_insert(b->cursor, &if_stmt->cf_node);
+
+ b->cursor = nir_after_cf_list(&if_stmt->then_list);
+ nir_store_var(b, color, texture_data[0], 0xf);
+
+ b->cursor = nir_after_cf_list(&if_stmt->else_list);
+ outer_if = if_stmt;
+ }
+
+ for (int j = 0; j < count_trailing_one_bits(i); j++) {
+ assert(stack_depth >= 2);
+ --stack_depth;
+
+ assert(dst_type == BRW_REGISTER_TYPE_F);
+ texture_data[stack_depth - 1] =
+ nir_fadd(b, texture_data[stack_depth - 1],
+ texture_data[stack_depth]);
+ }
+ }
+
+ /* We should have just 1 sample on the stack now. */
+ assert(stack_depth == 1);
+
+ texture_data[0] = nir_fmul(b, texture_data[0],
+ nir_imm_float(b, 1.0 / tex_samples));
+
+ nir_store_var(b, color, texture_data[0], 0xf);
+
+ if (outer_if)
+ b->cursor = nir_after_cf_node(&outer_if->cf_node);
+
+ return nir_load_var(b, color);
+}
+
+static inline nir_ssa_def *
+nir_imm_vec2(nir_builder *build, float x, float y)
+{
+ nir_const_value v;
+
+ memset(&v, 0, sizeof(v));
+ v.f32[0] = x;
+ v.f32[1] = y;
+
+ return nir_build_imm(build, 4, 32, v);
+}
+
+static nir_ssa_def *
+blorp_nir_manual_blend_bilinear(nir_builder *b, nir_ssa_def *pos,
+ unsigned tex_samples,
+ const brw_blorp_blit_prog_key *key,
+ struct brw_blorp_blit_vars *v)
+{
+ nir_ssa_def *pos_xy = nir_channels(b, pos, 0x3);
+
+ nir_ssa_def *scale = nir_imm_vec2(b, key->x_scale, key->y_scale);
+
+ /* Translate coordinates to lay out the samples in a rectangular grid
+ * roughly corresponding to sample locations.
+ */
+ pos_xy = nir_fmul(b, pos_xy, scale);
+ /* Adjust coordinates so that integers represent pixel centers rather
+ * than pixel edges.
+ */
+ pos_xy = nir_fadd(b, pos_xy, nir_imm_float(b, -0.5));
+ /* Clamp the X, Y texture coordinates to properly handle the sampling of
+ * texels on texture edges.
+ */
+ pos_xy = nir_fmin(b, nir_fmax(b, pos_xy, nir_imm_float(b, 0.0)),
+ nir_vec2(b, nir_load_var(b, v->u_rect_grid_x1),
+ nir_load_var(b, v->u_rect_grid_y1)));
+
+ /* Store the fractional parts to be used as bilinear interpolation
+ * coefficients.
+ */
+ nir_ssa_def *frac_xy = nir_ffract(b, pos_xy);
+ /* Round the float coordinates down to nearest integer */
+ pos_xy = nir_fdiv(b, nir_ftrunc(b, pos_xy), scale);
+
+ nir_ssa_def *tex_data[4];
+ for (unsigned i = 0; i < 4; ++i) {
+ float sample_off_x = (float)(i & 0x1) / key->x_scale;
+ float sample_off_y = (float)((i >> 1) & 0x1) / key->y_scale;
+ nir_ssa_def *sample_off = nir_imm_vec2(b, sample_off_x, sample_off_y);
+
+ nir_ssa_def *sample_coords = nir_fadd(b, pos_xy, sample_off);
+ nir_ssa_def *sample_coords_int = nir_f2i(b, sample_coords);
+
+ /* The MCS value we fetch has to match up with the pixel that we're
+ * sampling from. Since we sample from different pixels in each
+ * iteration of this "for" loop, the call to mcs_fetch() should be
+ * here inside the loop after computing the pixel coordinates.
+ */
+ nir_ssa_def *mcs = NULL;
+ if (key->tex_layout == INTEL_MSAA_LAYOUT_CMS)
+ mcs = blorp_nir_txf_ms_mcs(b, sample_coords_int);
+
+ /* Compute sample index and map the sample index to a sample number.
+ * Sample index layout shows the numbering of slots in a rectangular
+ * grid of samples with in a pixel. Sample number layout shows the
+ * rectangular grid of samples roughly corresponding to the real sample
+ * locations with in a pixel.
+ * In case of 4x MSAA, layout of sample indices matches the layout of
+ * sample numbers:
+ * ---------
+ * | 0 | 1 |
+ * ---------
+ * | 2 | 3 |
+ * ---------
+ *
+ * In case of 8x MSAA the two layouts don't match.
+ * sample index layout : --------- sample number layout : ---------
+ * | 0 | 1 | | 5 | 2 |
+ * --------- ---------
+ * | 2 | 3 | | 4 | 6 |
+ * --------- ---------
+ * | 4 | 5 | | 0 | 3 |
+ * --------- ---------
+ * | 6 | 7 | | 7 | 1 |
+ * --------- ---------
+ *
+ * Fortunately, this can be done fairly easily as:
+ * S' = (0x17306425 >> (S * 4)) & 0xf
+ */
+ nir_ssa_def *frac = nir_ffract(b, sample_coords);
+ nir_ssa_def *sample =
+ nir_fdot2(b, frac, nir_imm_vec2(b, key->x_scale,
+ key->x_scale * key->y_scale));
+ sample = nir_f2i(b, sample);
+
+ if (tex_samples == 8) {
+ sample = nir_iand(b, nir_ishr(b, nir_imm_int(b, 0x17306425),
+ nir_ishl(b, sample, nir_imm_int(b, 2))),
+ nir_imm_int(b, 0xf));
+ }
+ nir_ssa_def *pos_ms = nir_vec3(b, nir_channel(b, sample_coords_int, 0),
+ nir_channel(b, sample_coords_int, 1),
+ sample);
+ tex_data[i] = blorp_nir_txf_ms(b, pos_ms, mcs, key->texture_data_type);
+ }
+
+ nir_ssa_def *frac_x = nir_channel(b, frac_xy, 0);
+ nir_ssa_def *frac_y = nir_channel(b, frac_xy, 1);
+ return nir_flrp(b, nir_flrp(b, tex_data[0], tex_data[1], frac_x),
+ nir_flrp(b, tex_data[2], tex_data[3], frac_x),
+ frac_y);
+}
+
/**
* Generator for WM programs used in BLORP blits.
*
if (rt_tiled_w != key->dst_tiled_w ||
key->rt_samples != key->dst_samples ||
key->rt_layout != key->dst_layout) {
- if (key->rt_samples != key->dst_samples ||
- key->rt_layout != key->dst_layout ||
- key->rt_samples != 0)
- goto fail;
+ dst_pos = blorp_nir_encode_msaa(&b, dst_pos, key->rt_samples,
+ key->rt_layout);
+ /* Now (X, Y, S) = detile(rt_tiling, offset) */
if (rt_tiled_w != key->dst_tiled_w)
dst_pos = blorp_nir_retile_y_to_w(&b, dst_pos);
+ /* Now (X, Y, S) = detile(rt_tiling, offset) */
+ dst_pos = blorp_nir_decode_msaa(&b, dst_pos, key->dst_samples,
+ key->dst_layout);
}
/* Now (X, Y, S) = decode_msaa(dst_samples, detile(dst_tiling, offset)).
blorp_nir_discard_if_outside_rect(&b, dst_pos, &v);
src_pos = blorp_blit_apply_transform(&b, nir_i2f(&b, dst_pos), &v);
-
- if (key->blit_scaled && key->blend) {
- goto fail;
- } else if (!key->bilinear_filter) {
- /* We're going to use a texelFetch, so we need integers */
- src_pos = nir_f2i(&b, src_pos);
+ if (dst_pos->num_components == 3) {
+ /* The sample coordinate is an integer that we want left alone but
+ * blorp_blit_apply_transform() blindly applies the transform to all
+ * three coordinates. Grab the original sample index.
+ */
+ src_pos = nir_vec3(&b, nir_channel(&b, src_pos, 0),
+ nir_channel(&b, src_pos, 1),
+ nir_channel(&b, dst_pos, 2));
}
+ /* If the source image is not multisampled, then we want to fetch sample
+ * number 0, because that's the only sample there is.
+ */
+ if (key->src_samples == 0)
+ src_pos = nir_channels(&b, src_pos, 0x3);
+
/* X, Y, and S are now the coordinates of the pixel in the source image
* that we want to texture from. Exception: if we are blending, then S is
* irrelevant, because we are going to fetch all samples.
*/
if (key->blend && !key->blit_scaled) {
- goto fail;
- } else if (key->blend && key->blit_scaled) {
- goto fail;
- } else {
- /* We aren't blending, which means we just want to fetch a single sample
- * from the source surface. The address that we want to fetch from is
- * related to the X, Y and S values according to the formula:
- *
- * (X, Y, S) = decode_msaa(src_samples, detile(src_tiling, offset)).
- *
- * If the actual tiling and sample count of the source surface are not
- * the same as the configuration of the texture, then we need to adjust
- * the coordinates to compensate for the difference.
+ /* Resolves (effecively) use texelFetch, so we need integers and we
+ * don't care about the sample index if we got one.
*/
- if ((tex_tiled_w != key->src_tiled_w ||
- key->tex_samples != key->src_samples ||
- key->tex_layout != key->src_layout) &&
- !key->bilinear_filter) {
- if (key->tex_samples != key->src_samples ||
- key->tex_layout != key->src_layout ||
- key->tex_samples != 0)
- goto fail;
+ src_pos = nir_f2i(&b, nir_channels(&b, src_pos, 0x3));
- if (tex_tiled_w != key->src_tiled_w)
- src_pos = blorp_nir_retile_w_to_y(&b, src_pos);
+ if (brw->gen == 6) {
+ /* Because gen6 only supports 4x interleved MSAA, we can do all the
+ * blending we need with a single linear-interpolated texture lookup
+ * at the center of the sample. The texture coordinates to be odd
+ * integers so that they correspond to the center of a 2x2 block
+ * representing the four samples that maxe up a pixel. So we need
+ * to multiply our X and Y coordinates each by 2 and then add 1.
+ */
+ src_pos = nir_ishl(&b, src_pos, nir_imm_int(&b, 1));
+ src_pos = nir_iadd(&b, src_pos, nir_imm_int(&b, 1));
+ src_pos = nir_i2f(&b, src_pos);
+ color = blorp_nir_tex(&b, src_pos, key->texture_data_type);
+ } else {
+ /* Gen7+ hardware doesn't automaticaly blend. */
+ color = blorp_nir_manual_blend_average(&b, src_pos, key->src_samples,
+ key->src_layout,
+ key->texture_data_type);
}
-
+ } else if (key->blend && key->blit_scaled) {
+ color = blorp_nir_manual_blend_bilinear(&b, src_pos, key->src_samples, key, &v);
+ } else {
if (key->bilinear_filter) {
color = blorp_nir_tex(&b, src_pos, key->texture_data_type);
} else {
+ /* We're going to use texelFetch, so we need integers */
+ if (src_pos->num_components == 2) {
+ src_pos = nir_f2i(&b, src_pos);
+ } else {
+ assert(src_pos->num_components == 3);
+ src_pos = nir_vec3(&b, nir_channel(&b, nir_f2i(&b, src_pos), 0),
+ nir_channel(&b, nir_f2i(&b, src_pos), 1),
+ nir_channel(&b, src_pos, 2));
+ }
+
+ /* We aren't blending, which means we just want to fetch a single
+ * sample from the source surface. The address that we want to fetch
+ * from is related to the X, Y and S values according to the formula:
+ *
+ * (X, Y, S) = decode_msaa(src_samples, detile(src_tiling, offset)).
+ *
+ * If the actual tiling and sample count of the source surface are
+ * not the same as the configuration of the texture, then we need to
+ * adjust the coordinates to compensate for the difference.
+ */
+ if (tex_tiled_w != key->src_tiled_w ||
+ key->tex_samples != key->src_samples ||
+ key->tex_layout != key->src_layout) {
+ src_pos = blorp_nir_encode_msaa(&b, src_pos, key->src_samples,
+ key->src_layout);
+ /* Now (X, Y, S) = detile(src_tiling, offset) */
+ if (tex_tiled_w != key->src_tiled_w)
+ src_pos = blorp_nir_retile_w_to_y(&b, src_pos);
+ /* Now (X, Y, S) = detile(tex_tiling, offset) */
+ src_pos = blorp_nir_decode_msaa(&b, src_pos, key->tex_samples,
+ key->tex_layout);
+ }
+
/* Now (X, Y, S) = decode_msaa(tex_samples, detile(tex_tiling, offset)).
*
* In other words: X, Y, and S now contain values which, when passed to
nir_store_var(&b, v.color_out, color, 0xf);
return b.shader;
-
-fail:
- ralloc_free(b.shader);
- return NULL;
}
class brw_blorp_blit_program : public brw_blorp_eu_emitter
-/**
- * Count the number of trailing 1 bits in the given value. For example:
- *
- * count_trailing_one_bits(0) == 0
- * count_trailing_one_bits(7) == 3
- * count_trailing_one_bits(11) == 2
- */
-static inline int count_trailing_one_bits(unsigned value)
-{
-#ifdef HAVE___BUILTIN_CTZ
- return __builtin_ctz(~value);
-#else
- return _mesa_bitcount(value & ~(value + 1));
-#endif
-}
-
-
void
brw_blorp_blit_program::manual_blend_average(unsigned num_samples)
{