gallivm: Allow to force nearest filtering on a per-axis basis.

Experimental code, not really used yet.
This commit is contained in:
José Fonseca 2012-07-13 18:27:43 +01:00
parent b262f56738
commit ba9c1773d7
2 changed files with 75 additions and 43 deletions

View file

@ -86,6 +86,10 @@ struct lp_sampler_static_state
unsigned lod_bias_non_zero:1;
unsigned apply_min_lod:1; /**< min_lod > 0 ? */
unsigned apply_max_lod:1; /**< max_lod < last_level ? */
/* Hacks */
unsigned force_nearest_s:1;
unsigned force_nearest_t:1;
};

View file

@ -498,8 +498,10 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
/* subtract 0.5 (add -128) */
i32_c128 = lp_build_const_int_vec(bld->gallivm, i32.type, -128);
s = LLVMBuildAdd(builder, s, i32_c128, "");
if (dims >= 2) {
if (!bld->static_state->force_nearest_s) {
s = LLVMBuildAdd(builder, s, i32_c128, "");
}
if (dims >= 2 && !bld->static_state->force_nearest_t) {
t = LLVMBuildAdd(builder, t, i32_c128, "");
}
if (dims >= 3) {
@ -716,56 +718,82 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
/*
* Linear interpolation with 8.8 fixed point.
*/
if (dims == 1) {
/* 1-D lerp */
if (bld->static_state->force_nearest_s) {
/* special case 1-D lerp */
packed_lo = lp_build_lerp(&h16,
s_fpart_lo,
neighbors_lo[0][0][0],
neighbors_lo[0][0][1]);
t_fpart_lo,
neighbors_lo[0][0][0],
neighbors_lo[0][0][1]);
packed_hi = lp_build_lerp(&h16,
s_fpart_hi,
neighbors_hi[0][0][0],
neighbors_hi[0][0][1]);
t_fpart_hi,
neighbors_hi[0][1][0],
neighbors_hi[0][1][0]);
}
else if (bld->static_state->force_nearest_t) {
/* special case 1-D lerp */
packed_lo = lp_build_lerp(&h16,
s_fpart_lo,
neighbors_lo[0][0][0],
neighbors_lo[0][0][1]);
packed_hi = lp_build_lerp(&h16,
s_fpart_hi,
neighbors_hi[0][0][0],
neighbors_hi[0][0][1]);
}
else {
/* 2-D lerp */
packed_lo = lp_build_lerp_2d(&h16,
s_fpart_lo, t_fpart_lo,
neighbors_lo[0][0][0],
neighbors_lo[0][0][1],
neighbors_lo[0][1][0],
neighbors_lo[0][1][1]);
/* general 1/2/3-D lerping */
if (dims == 1) {
packed_lo = lp_build_lerp(&h16,
s_fpart_lo,
neighbors_lo[0][0][0],
neighbors_lo[0][0][1]);
packed_hi = lp_build_lerp_2d(&h16,
s_fpart_hi, t_fpart_hi,
neighbors_hi[0][0][0],
neighbors_hi[0][0][1],
neighbors_hi[0][1][0],
neighbors_hi[0][1][1]);
packed_hi = lp_build_lerp(&h16,
s_fpart_hi,
neighbors_hi[0][0][0],
neighbors_hi[0][0][1]);
}
else {
/* 2-D lerp */
packed_lo = lp_build_lerp_2d(&h16,
s_fpart_lo, t_fpart_lo,
neighbors_lo[0][0][0],
neighbors_lo[0][0][1],
neighbors_lo[0][1][0],
neighbors_lo[0][1][1]);
if (dims >= 3) {
LLVMValueRef packed_lo2, packed_hi2;
packed_hi = lp_build_lerp_2d(&h16,
s_fpart_hi, t_fpart_hi,
neighbors_hi[0][0][0],
neighbors_hi[0][0][1],
neighbors_hi[0][1][0],
neighbors_hi[0][1][1]);
/* lerp in the second z slice */
packed_lo2 = lp_build_lerp_2d(&h16,
s_fpart_lo, t_fpart_lo,
neighbors_lo[1][0][0],
neighbors_lo[1][0][1],
neighbors_lo[1][1][0],
neighbors_lo[1][1][1]);
if (dims >= 3) {
LLVMValueRef packed_lo2, packed_hi2;
packed_hi2 = lp_build_lerp_2d(&h16,
s_fpart_hi, t_fpart_hi,
neighbors_hi[1][0][0],
neighbors_hi[1][0][1],
neighbors_hi[1][1][0],
neighbors_hi[1][1][1]);
/* interp between two z slices */
packed_lo = lp_build_lerp(&h16, r_fpart_lo,
packed_lo, packed_lo2);
packed_hi = lp_build_lerp(&h16, r_fpart_hi,
packed_hi, packed_hi2);
/* lerp in the second z slice */
packed_lo2 = lp_build_lerp_2d(&h16,
s_fpart_lo, t_fpart_lo,
neighbors_lo[1][0][0],
neighbors_lo[1][0][1],
neighbors_lo[1][1][0],
neighbors_lo[1][1][1]);
packed_hi2 = lp_build_lerp_2d(&h16,
s_fpart_hi, t_fpart_hi,
neighbors_hi[1][0][0],
neighbors_hi[1][0][1],
neighbors_hi[1][1][0],
neighbors_hi[1][1][1]);
/* interp between two z slices */
packed_lo = lp_build_lerp(&h16, r_fpart_lo,
packed_lo, packed_lo2);
packed_hi = lp_build_lerp(&h16, r_fpart_hi,
packed_hi, packed_hi2);
}
}
}